@@ -7,6 +7,7 @@ import 'package:devtools_test/helpers.dart';
77import 'package:flutter/gestures.dart' ;
88import 'package:flutter/material.dart' ;
99import 'package:flutter_test/flutter_test.dart' ;
10+ import 'package:provider/provider.dart' ;
1011
1112void main () {
1213 Future <void > pumpHoverCardTooltip (
@@ -108,4 +109,120 @@ void main() {
108109 expect (overlayContainer, findsOneWidget);
109110 },
110111 );
112+
113+ testWidgetsWithWindowSize (
114+ 'HoverCard height clamping with title' ,
115+ const Size (800 , 600 ),
116+ (WidgetTester tester) async {
117+ await pumpHoverCardTooltip (
118+ tester,
119+ alignment: Alignment .bottomCenter,
120+ title: 'An Important Title' ,
121+ );
122+
123+ final hoverContentFinderWithTitle = find.text ('Hover Content' );
124+ expect (hoverContentFinderWithTitle, findsOneWidget);
125+
126+ final containerWithTitle = find
127+ .ancestor (of: hoverContentFinderWithTitle, matching: find.byType (Container ))
128+ .last;
129+
130+ final renderBoxWithTitle =
131+ tester.renderObject (containerWithTitle) as RenderBox ;
132+ final positionWithTitle = renderBoxWithTitle.localToGlobal (Offset .zero);
133+
134+ // Clamps strictly at y = 274.0 because of dynamic height containing title/divider.
135+ expect (positionWithTitle.dy, equals (274.0 ));
136+ },
137+ );
138+
139+ testWidgetsWithWindowSize (
140+ 'HoverCard height clamping without title' ,
141+ const Size (800 , 600 ),
142+ (WidgetTester tester) async {
143+ await pumpHoverCardTooltip (
144+ tester,
145+ alignment: Alignment .bottomCenter,
146+ );
147+
148+ final hoverContentFinderNoTitle = find.text ('Hover Content' );
149+ expect (hoverContentFinderNoTitle, findsOneWidget);
150+
151+ final containerNoTitle = find
152+ .ancestor (of: hoverContentFinderNoTitle, matching: find.byType (Container ))
153+ .last;
154+
155+ final renderBoxNoTitle =
156+ tester.renderObject (containerNoTitle) as RenderBox ;
157+ final positionNoTitle = renderBoxNoTitle.localToGlobal (Offset .zero);
158+
159+ // Clamps lower down at y = 314.0 because max height is smaller without title gaps.
160+ expect (positionNoTitle.dy, equals (314.0 ));
161+ },
162+ );
163+
164+ testWidgetsWithWindowSize (
165+ 'HoverCard translates global coordinates to local coordinates for offset overlays' ,
166+ const Size (800 , 600 ),
167+ (WidgetTester tester) async {
168+ final overlayKey = GlobalKey ();
169+
170+ await tester.pumpWidget (
171+ MaterialApp (
172+ home: Scaffold (
173+ body: Padding (
174+ padding: const EdgeInsets .only (left: 50.0 , top: 100.0 ),
175+ child: Provider <HoverCardController >.value (
176+ value: HoverCardController (),
177+ child: Overlay (
178+ key: overlayKey,
179+ initialEntries: [
180+ OverlayEntry (
181+ builder: (context) => Align (
182+ alignment: Alignment .topLeft,
183+ child: HoverCardTooltip .sync (
184+ enabled: () => true ,
185+ generateHoverCardData: (event) => HoverCardData (
186+ contents: const SizedBox (
187+ width: 200 ,
188+ height: 250 ,
189+ child: Text ('Hover Content' ),
190+ ),
191+ ),
192+ child: const Text ('Hover Me Offset' ),
193+ ),
194+ ),
195+ ),
196+ ],
197+ ),
198+ ),
199+ ),
200+ ),
201+ ),
202+ );
203+
204+ // Trigger hover
205+ final gesture = await tester.createGesture (kind: PointerDeviceKind .mouse);
206+ await gesture.addPointer (location: Offset .zero);
207+
208+ final center = tester.getCenter (find.text ('Hover Me Offset' ));
209+ await gesture.moveTo (center);
210+ await tester.pump (const Duration (milliseconds: 500 ));
211+ await tester.pumpAndSettle ();
212+
213+ final hoverContentFinder = find.text ('Hover Content' );
214+ expect (hoverContentFinder, findsOneWidget);
215+
216+ final overlayContainer = find
217+ .ancestor (of: hoverContentFinder, matching: find.byType (Container ))
218+ .last;
219+
220+ final renderBox = tester.renderObject (overlayContainer) as RenderBox ;
221+ final position = renderBox.localToGlobal (Offset .zero);
222+
223+ // Dynamic margin is 16.0. Since overlay is offset by 50px globally at the left,
224+ // dynamic local X is 16.0, mapped to global X = 50.0 + 16.0 = 66.0.
225+ expect (position.dx, equals (66.0 ));
226+ },
227+ );
111228}
0 commit comments