Jaime Blasco
Committed by GitHub

test: increase test coverage (#267)

@@ -13,7 +13,7 @@ jobs: @@ -13,7 +13,7 @@ jobs:
13 uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1 13 uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1
14 with: 14 with:
15 working_directory: sheet 15 working_directory: sheet
16 - min_coverage: 60 # Working to reach 100% XD 16 + min_coverage: 70 # Working to reach 100% XD
17 17
18 pana: 18 pana:
19 uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/pana.yml@v1 19 uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/pana.yml@v1
@@ -21,6 +21,6 @@ @@ -21,6 +21,6 @@
21 <key>CFBundleVersion</key> 21 <key>CFBundleVersion</key>
22 <string>1.0</string> 22 <string>1.0</string>
23 <key>MinimumOSVersion</key> 23 <key>MinimumOSVersion</key>
24 - <string>9.0</string> 24 + <string>11.0</string>
25 </dict> 25 </dict>
26 </plist> 26 </plist>
@@ -272,7 +272,7 @@ @@ -272,7 +272,7 @@
272 GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 272 GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
273 GCC_WARN_UNUSED_FUNCTION = YES; 273 GCC_WARN_UNUSED_FUNCTION = YES;
274 GCC_WARN_UNUSED_VARIABLE = YES; 274 GCC_WARN_UNUSED_VARIABLE = YES;
275 - IPHONEOS_DEPLOYMENT_TARGET = 9.0; 275 + IPHONEOS_DEPLOYMENT_TARGET = 11.0;
276 MTL_ENABLE_DEBUG_INFO = NO; 276 MTL_ENABLE_DEBUG_INFO = NO;
277 SDKROOT = iphoneos; 277 SDKROOT = iphoneos;
278 SUPPORTED_PLATFORMS = iphoneos; 278 SUPPORTED_PLATFORMS = iphoneos;
@@ -358,7 +358,7 @@ @@ -358,7 +358,7 @@
358 GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 358 GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
359 GCC_WARN_UNUSED_FUNCTION = YES; 359 GCC_WARN_UNUSED_FUNCTION = YES;
360 GCC_WARN_UNUSED_VARIABLE = YES; 360 GCC_WARN_UNUSED_VARIABLE = YES;
361 - IPHONEOS_DEPLOYMENT_TARGET = 9.0; 361 + IPHONEOS_DEPLOYMENT_TARGET = 11.0;
362 MTL_ENABLE_DEBUG_INFO = YES; 362 MTL_ENABLE_DEBUG_INFO = YES;
363 ONLY_ACTIVE_ARCH = YES; 363 ONLY_ACTIVE_ARCH = YES;
364 SDKROOT = iphoneos; 364 SDKROOT = iphoneos;
@@ -407,7 +407,7 @@ @@ -407,7 +407,7 @@
407 GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 407 GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
408 GCC_WARN_UNUSED_FUNCTION = YES; 408 GCC_WARN_UNUSED_FUNCTION = YES;
409 GCC_WARN_UNUSED_VARIABLE = YES; 409 GCC_WARN_UNUSED_VARIABLE = YES;
410 - IPHONEOS_DEPLOYMENT_TARGET = 9.0; 410 + IPHONEOS_DEPLOYMENT_TARGET = 11.0;
411 MTL_ENABLE_DEBUG_INFO = NO; 411 MTL_ENABLE_DEBUG_INFO = NO;
412 SDKROOT = iphoneos; 412 SDKROOT = iphoneos;
413 SUPPORTED_PLATFORMS = iphoneos; 413 SUPPORTED_PLATFORMS = iphoneos;
@@ -4,41 +4,25 @@ import 'package:flutter/material.dart'; @@ -4,41 +4,25 @@ import 'package:flutter/material.dart';
4 import 'package:flutter/widgets.dart'; 4 import 'package:flutter/widgets.dart';
5 import 'package:sheet/sheet.dart'; 5 import 'package:sheet/sheet.dart';
6 6
7 -class FitSheet extends StatefulWidget {  
8 - @override  
9 - _FitSheetState createState() => _FitSheetState();  
10 -}  
11 -  
12 -class _FitSheetState extends State<FitSheet> {  
13 - final SheetController controller = SheetController();  
14 -  
15 - @override  
16 - void initState() {  
17 - Future<void>.delayed(const Duration(milliseconds: 400), animateSheet);  
18 -  
19 - super.initState();  
20 - }  
21 -  
22 - void animateSheet() {  
23 - controller.relativeAnimateTo(1,  
24 - duration: const Duration(milliseconds: 400), curve: Curves.easeOut);  
25 - }  
26 -  
27 - @override  
28 - void dispose() {  
29 - controller.dispose();  
30 - super.dispose();  
31 - }  
32 - 7 +class FitSheet extends StatelessWidget {
33 @override 8 @override
34 Widget build(BuildContext context) { 9 Widget build(BuildContext context) {
35 - return Sheet(  
36 - elevation: 4,  
37 - child: Container(  
38 - height: 400,  
39 - child: const Text('hello'), 10 + return DefaultSheetController(
  11 + onCreated: (controller) async {
  12 + await Future<void>.delayed(const Duration(milliseconds: 400));
  13 + controller.relativeAnimateTo(
  14 + 1,
  15 + duration: const Duration(milliseconds: 400),
  16 + curve: Curves.easeOut,
  17 + );
  18 + },
  19 + child: Sheet(
  20 + elevation: 4,
  21 + child: Container(
  22 + height: 400,
  23 + child: const Text('hello'),
  24 + ),
40 ), 25 ),
41 - controller: controller,  
42 ); 26 );
43 } 27 }
44 } 28 }
@@ -7,7 +7,7 @@ packages: @@ -7,7 +7,7 @@ packages:
7 name: async 7 name: async
8 url: "https://pub.dartlang.org" 8 url: "https://pub.dartlang.org"
9 source: hosted 9 source: hosted
10 - version: "2.8.2" 10 + version: "2.9.0"
11 boolean_selector: 11 boolean_selector:
12 dependency: transitive 12 dependency: transitive
13 description: 13 description:
@@ -21,21 +21,14 @@ packages: @@ -21,21 +21,14 @@ packages:
21 name: characters 21 name: characters
22 url: "https://pub.dartlang.org" 22 url: "https://pub.dartlang.org"
23 source: hosted 23 source: hosted
24 - version: "1.2.0"  
25 - charcode:  
26 - dependency: transitive  
27 - description:  
28 - name: charcode  
29 - url: "https://pub.dartlang.org"  
30 - source: hosted  
31 - version: "1.3.1" 24 + version: "1.2.1"
32 clock: 25 clock:
33 dependency: transitive 26 dependency: transitive
34 description: 27 description:
35 name: clock 28 name: clock
36 url: "https://pub.dartlang.org" 29 url: "https://pub.dartlang.org"
37 source: hosted 30 source: hosted
38 - version: "1.1.0" 31 + version: "1.1.1"
39 collection: 32 collection:
40 dependency: transitive 33 dependency: transitive
41 description: 34 description:
@@ -63,7 +56,7 @@ packages: @@ -63,7 +56,7 @@ packages:
63 name: fake_async 56 name: fake_async
64 url: "https://pub.dartlang.org" 57 url: "https://pub.dartlang.org"
65 source: hosted 58 source: hosted
66 - version: "1.3.0" 59 + version: "1.3.1"
67 flutter: 60 flutter:
68 dependency: "direct main" 61 dependency: "direct main"
69 description: flutter 62 description: flutter
@@ -106,21 +99,21 @@ packages: @@ -106,21 +99,21 @@ packages:
106 name: matcher 99 name: matcher
107 url: "https://pub.dartlang.org" 100 url: "https://pub.dartlang.org"
108 source: hosted 101 source: hosted
109 - version: "0.12.11" 102 + version: "0.12.12"
110 material_color_utilities: 103 material_color_utilities:
111 dependency: transitive 104 dependency: transitive
112 description: 105 description:
113 name: material_color_utilities 106 name: material_color_utilities
114 url: "https://pub.dartlang.org" 107 url: "https://pub.dartlang.org"
115 source: hosted 108 source: hosted
116 - version: "0.1.4" 109 + version: "0.1.5"
117 meta: 110 meta:
118 dependency: transitive 111 dependency: transitive
119 description: 112 description:
120 name: meta 113 name: meta
121 url: "https://pub.dartlang.org" 114 url: "https://pub.dartlang.org"
122 source: hosted 115 source: hosted
123 - version: "1.7.0" 116 + version: "1.8.0"
124 nested: 117 nested:
125 dependency: transitive 118 dependency: transitive
126 description: 119 description:
@@ -134,7 +127,7 @@ packages: @@ -134,7 +127,7 @@ packages:
134 name: path 127 name: path
135 url: "https://pub.dartlang.org" 128 url: "https://pub.dartlang.org"
136 source: hosted 129 source: hosted
137 - version: "1.8.1" 130 + version: "1.8.2"
138 provider: 131 provider:
139 dependency: "direct main" 132 dependency: "direct main"
140 description: 133 description:
@@ -160,7 +153,7 @@ packages: @@ -160,7 +153,7 @@ packages:
160 name: source_span 153 name: source_span
161 url: "https://pub.dartlang.org" 154 url: "https://pub.dartlang.org"
162 source: hosted 155 source: hosted
163 - version: "1.8.2" 156 + version: "1.9.0"
164 stack_trace: 157 stack_trace:
165 dependency: transitive 158 dependency: transitive
166 description: 159 description:
@@ -181,21 +174,21 @@ packages: @@ -181,21 +174,21 @@ packages:
181 name: string_scanner 174 name: string_scanner
182 url: "https://pub.dartlang.org" 175 url: "https://pub.dartlang.org"
183 source: hosted 176 source: hosted
184 - version: "1.1.0" 177 + version: "1.1.1"
185 term_glyph: 178 term_glyph:
186 dependency: transitive 179 dependency: transitive
187 description: 180 description:
188 name: term_glyph 181 name: term_glyph
189 url: "https://pub.dartlang.org" 182 url: "https://pub.dartlang.org"
190 source: hosted 183 source: hosted
191 - version: "1.2.0" 184 + version: "1.2.1"
192 test_api: 185 test_api:
193 dependency: transitive 186 dependency: transitive
194 description: 187 description:
195 name: test_api 188 name: test_api
196 url: "https://pub.dartlang.org" 189 url: "https://pub.dartlang.org"
197 source: hosted 190 source: hosted
198 - version: "0.4.9" 191 + version: "0.4.12"
199 vector_math: 192 vector_math:
200 dependency: transitive 193 dependency: transitive
201 description: 194 description:
@@ -205,4 +198,4 @@ packages: @@ -205,4 +198,4 @@ packages:
205 version: "2.1.2" 198 version: "2.1.2"
206 sdks: 199 sdks:
207 dart: ">=2.17.0 <3.0.0" 200 dart: ">=2.17.0 <3.0.0"
208 - flutter: ">=3.0.0" 201 + flutter: ">=3.3.0"
@@ -2,3 +2,5 @@ export 'src/physics.dart'; @@ -2,3 +2,5 @@ export 'src/physics.dart';
2 export 'src/scroll_controller.dart'; 2 export 'src/scroll_controller.dart';
3 export 'src/scrollable.dart'; 3 export 'src/scrollable.dart';
4 export 'src/sheet.dart'; 4 export 'src/sheet.dart';
  5 +export 'src/widgets/default_sheet_controller.dart';
  6 +export 'src/widgets/sheet_media_query.dart';
@@ -272,7 +272,7 @@ class Sheet extends StatelessWidget { @@ -272,7 +272,7 @@ class Sheet extends StatelessWidget {
272 offset: offset, 272 offset: offset,
273 minExtent: minResizableExtent ?? 0, 273 minExtent: minResizableExtent ?? 0,
274 child: Builder( 274 child: Builder(
275 - key: const Key('_sheet_builder'), 275 + key: const Key('_sheet_child'),
276 builder: (BuildContext context) { 276 builder: (BuildContext context) {
277 return decorationBuilder( 277 return decorationBuilder(
278 context, 278 context,
@@ -290,45 +290,6 @@ class Sheet extends StatelessWidget { @@ -290,45 +290,6 @@ class Sheet extends StatelessWidget {
290 } 290 }
291 } 291 }
292 292
293 -class SheetMediaQuery extends StatelessWidget {  
294 - const SheetMediaQuery({Key? key, required this.child}) : super(key: key);  
295 -  
296 - final Widget child;  
297 -  
298 - @override  
299 - Widget build(BuildContext context) {  
300 - final SheetPosition position = Sheet.of(context)!.controller.position;  
301 - final EdgeInsets padding = MediaQuery.of(context).padding;  
302 - return LayoutBuilder(  
303 - builder: (  
304 - BuildContext context,  
305 - BoxConstraints constraints,  
306 - ) {  
307 - return AnimatedBuilder(  
308 - animation: position,  
309 - builder: (BuildContext context, Widget? child) {  
310 - final double pixels = position.hasPixels ? position.pixels : 0;  
311 - final double viewportDimension = position.hasViewportDimension  
312 - ? position.viewportDimension  
313 - : double.infinity;  
314 - final double top = math.max(  
315 - 0.0,  
316 - padding.top - (viewportDimension - pixels),  
317 - );  
318 - return MediaQuery(  
319 - data: MediaQuery.of(context).copyWith(  
320 - padding: padding.copyWith(top: top),  
321 - ),  
322 - child: child!,  
323 - );  
324 - },  
325 - child: child,  
326 - );  
327 - },  
328 - );  
329 - }  
330 -}  
331 -  
332 class _DefaultSheetScrollController extends StatelessWidget { 293 class _DefaultSheetScrollController extends StatelessWidget {
333 const _DefaultSheetScrollController({Key? key, required this.child}) 294 const _DefaultSheetScrollController({Key? key, required this.child})
334 : super(key: key); 295 : super(key: key);
@@ -436,61 +397,6 @@ class SheetController extends ScrollController { @@ -436,61 +397,6 @@ class SheetController extends ScrollController {
436 } 397 }
437 } 398 }
438 399
439 -typedef SheetControllerCallback = void Function(SheetController controller);  
440 -  
441 -class DefaultSheetController extends StatefulWidget {  
442 - const DefaultSheetController({Key? key, required this.child, this.onCreated})  
443 - : super(key: key);  
444 -  
445 - final Widget child;  
446 -  
447 - final SheetControllerCallback? onCreated;  
448 -  
449 - static SheetController? of(BuildContext context) {  
450 - return context  
451 - .dependOnInheritedWidgetOfExactType<_InheritedSheetController>()  
452 - ?.controller;  
453 - }  
454 -  
455 - @override  
456 - State<DefaultSheetController> createState() => _DefaultSheetControllerState();  
457 -}  
458 -  
459 -class _DefaultSheetControllerState extends State<DefaultSheetController> {  
460 - late final SheetController controller = SheetController();  
461 -  
462 - @override  
463 - void initState() {  
464 - widget.onCreated?.call(controller);  
465 - super.initState();  
466 - }  
467 -  
468 - @override  
469 - Widget build(BuildContext context) {  
470 - return _InheritedSheetController(  
471 - child: widget.child, controller: controller);  
472 - }  
473 -  
474 - @override  
475 - void dispose() {  
476 - controller.dispose();  
477 - super.dispose();  
478 - }  
479 -}  
480 -  
481 -class _InheritedSheetController extends InheritedWidget {  
482 - const _InheritedSheetController(  
483 - {Key? key, required super.child, required this.controller})  
484 - : super(key: key);  
485 -  
486 - final SheetController controller;  
487 -  
488 - @override  
489 - bool updateShouldNotify(_InheritedSheetController oldWidget) {  
490 - return false;  
491 - }  
492 -}  
493 -  
494 /// A scroll position that manages scroll activities for 400 /// A scroll position that manages scroll activities for
495 /// [_SheetScrollController]. 401 /// [_SheetScrollController].
496 /// 402 ///
@@ -528,8 +434,11 @@ class SheetPosition extends ScrollPositionWithSingleContext { @@ -528,8 +434,11 @@ class SheetPosition extends ScrollPositionWithSingleContext {
528 Future<void> relativeAnimateTo(double to, 434 Future<void> relativeAnimateTo(double to,
529 {required Duration duration, required Curve curve}) { 435 {required Duration duration, required Curve curve}) {
530 assert(to >= 0 && to <= 1); 436 assert(to >= 0 && to <= 1);
531 - return super  
532 - .animateTo(to * maxScrollExtent, duration: duration, curve: curve); 437 + return super.animateTo(
  438 + pixelsFromRelativeOffset(to, minScrollExtent, maxScrollExtent),
  439 + duration: duration,
  440 + curve: curve,
  441 + );
533 } 442 }
534 443
535 @override 444 @override
@@ -541,7 +450,9 @@ class SheetPosition extends ScrollPositionWithSingleContext { @@ -541,7 +450,9 @@ class SheetPosition extends ScrollPositionWithSingleContext {
541 450
542 void relativeJumpTo(double to) { 451 void relativeJumpTo(double to) {
543 assert(to >= 0 && to <= 1); 452 assert(to >= 0 && to <= 1);
544 - return super.jumpTo(to * maxScrollExtent); 453 + final value =
  454 + pixelsFromRelativeOffset(to, minScrollExtent, maxScrollExtent);
  455 + return super.jumpTo(value);
545 } 456 }
546 457
547 @override 458 @override
@@ -567,13 +478,21 @@ class SheetPosition extends ScrollPositionWithSingleContext { @@ -567,13 +478,21 @@ class SheetPosition extends ScrollPositionWithSingleContext {
567 478
568 @override 479 @override
569 double setPixels(double newPixels) { 480 double setPixels(double newPixels) {
570 - _controller.value = (newPixels / maxScrollExtent).clamp(0, 1); 481 + _controller.value = relativeOffsetFromPixels(
  482 + newPixels,
  483 + minScrollExtent,
  484 + maxScrollExtent,
  485 + );
571 return super.setPixels(newPixels); 486 return super.setPixels(newPixels);
572 } 487 }
573 488
574 @override 489 @override
575 void forcePixels(double value) { 490 void forcePixels(double value) {
576 - _controller.value = (value / maxScrollExtent).clamp(0, 1); 491 + _controller.value = relativeOffsetFromPixels(
  492 + value,
  493 + minScrollExtent,
  494 + maxScrollExtent,
  495 + );
577 super.forcePixels(value); 496 super.forcePixels(value);
578 } 497 }
579 498
@@ -589,9 +508,34 @@ class SheetPosition extends ScrollPositionWithSingleContext { @@ -589,9 +508,34 @@ class SheetPosition extends ScrollPositionWithSingleContext {
589 // Clamp initial extent to maxScrollExtent 508 // Clamp initial extent to maxScrollExtent
590 if (!hasContentDimensions) { 509 if (!hasContentDimensions) {
591 correctPixels(pixels.clamp(minScrollExtent, maxScrollExtent)); 510 correctPixels(pixels.clamp(minScrollExtent, maxScrollExtent));
  511 + _controller.value = relativeOffsetFromPixels(
  512 + pixels,
  513 + minScrollExtent,
  514 + maxScrollExtent,
  515 + );
592 } 516 }
593 return super.applyContentDimensions(minScrollExtent, maxScrollExtent); 517 return super.applyContentDimensions(minScrollExtent, maxScrollExtent);
594 } 518 }
  519 +
  520 + static double relativeOffsetFromPixels(
  521 + double pixels,
  522 + double minScrollExtent,
  523 + double maxScrollExtent,
  524 + ) {
  525 + if (minScrollExtent == maxScrollExtent) return 1;
  526 + final value =
  527 + ((pixels - minScrollExtent) / (maxScrollExtent - minScrollExtent))
  528 + .clamp(0.0, 1.0);
  529 + return value;
  530 + }
  531 +
  532 + static double pixelsFromRelativeOffset(
  533 + double offset,
  534 + double minScrollExtent,
  535 + double maxScrollExtent,
  536 + ) {
  537 + return minScrollExtent + offset * (maxScrollExtent - minScrollExtent);
  538 + }
595 } 539 }
596 540
597 class SheetViewport extends SingleChildRenderObjectWidget { 541 class SheetViewport extends SingleChildRenderObjectWidget {
  1 +import 'package:flutter/material.dart';
  2 +import 'package:sheet/sheet.dart';
  3 +
  4 +typedef SheetControllerCallback = void Function(SheetController controller);
  5 +
  6 +/// A widget that injets a [SheetController] that can be used by
  7 +/// any [Sheet] children
  8 +///
  9 +/// It is useful for creating initial animations
  10 +/// ```dart
  11 +/// DefaultSheetController(
  12 +/// onCreated: (controller) => controller.play
  13 +/// )
  14 +///
  15 +///
  16 +class DefaultSheetController extends StatefulWidget {
  17 + const DefaultSheetController({Key? key, required this.child, this.onCreated})
  18 + : super(key: key);
  19 +
  20 + final Widget child;
  21 +
  22 + /// A callback called when the controller is created
  23 + final SheetControllerCallback? onCreated;
  24 +
  25 + static SheetController? of(BuildContext context) {
  26 + return context
  27 + .dependOnInheritedWidgetOfExactType<_InheritedSheetController>()
  28 + ?.controller;
  29 + }
  30 +
  31 + @override
  32 + State<DefaultSheetController> createState() => _DefaultSheetControllerState();
  33 +}
  34 +
  35 +class _DefaultSheetControllerState extends State<DefaultSheetController> {
  36 + late final SheetController controller = SheetController();
  37 +
  38 + @override
  39 + void initState() {
  40 + widget.onCreated?.call(controller);
  41 + super.initState();
  42 + }
  43 +
  44 + @override
  45 + Widget build(BuildContext context) {
  46 + return _InheritedSheetController(
  47 + child: widget.child, controller: controller);
  48 + }
  49 +
  50 + @override
  51 + void dispose() {
  52 + controller.dispose();
  53 + super.dispose();
  54 + }
  55 +}
  56 +
  57 +class _InheritedSheetController extends InheritedWidget {
  58 + const _InheritedSheetController(
  59 + {Key? key, required super.child, required this.controller})
  60 + : super(key: key);
  61 +
  62 + final SheetController controller;
  63 +
  64 + @override
  65 + bool updateShouldNotify(_InheritedSheetController oldWidget) {
  66 + return false;
  67 + }
  68 +}
  1 +import 'package:flutter/widgets.dart';
  2 +import 'package:sheet/sheet.dart';
  3 +import 'dart:math' as math;
  4 +
  5 +/// A widget that updates the top safe area proportionally to the position
  6 +/// of the sheet
  7 +///
  8 +/// If the sheet is below the top safe area the inner top padding will be 0.
  9 +/// Once the sheet enters the top safe area the inner top padding will increase
  10 +/// proportionally to the sheet offset.
  11 +/// If the sheet is fully expanded to the top of the screen the top padding
  12 +/// will be the same as the parent top safe area.
  13 +class SheetMediaQuery extends StatelessWidget {
  14 + const SheetMediaQuery({Key? key, required this.child}) : super(key: key);
  15 +
  16 + final Widget child;
  17 +
  18 + @override
  19 + Widget build(BuildContext context) {
  20 + final controller = Sheet.of(context)!.controller;
  21 + final MediaQueryData data = MediaQuery.of(context);
  22 + return LayoutBuilder(builder: (context, constraints) {
  23 + return AnimatedBuilder(
  24 + animation: controller.animation,
  25 + builder: (BuildContext context, Widget? child) {
  26 + final position = controller.position;
  27 + final viewportDimension = position.hasViewportDimension
  28 + ? position.viewportDimension
  29 + : double.infinity;
  30 + final pixels = position.hasPixels ? position.pixels : 0;
  31 + final offset = viewportDimension - pixels;
  32 + final topPadding = math.max(0.0, data.padding.top - offset);
  33 + return MediaQuery(
  34 + data: data.copyWith(
  35 + padding: data.padding.copyWith(
  36 + top: topPadding,
  37 + ),
  38 + ),
  39 + child: child!,
  40 + );
  41 + },
  42 + child: child,
  43 + );
  44 + });
  45 + }
  46 +}
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_test/flutter_test.dart';
  3 +import 'package:sheet/sheet.dart';
  4 +
  5 +import '../helpers.dart';
  6 +
  7 +void main() {
  8 + group('SheetController.animation', () {
  9 + testWidgets('is 0 when starts in minExtent', (tester) async {
  10 + await tester.pumpWidget(
  11 + MaterialApp(
  12 + home: Sheet(
  13 + minExtent: 100,
  14 + maxExtent: 400,
  15 + initialExtent: 100,
  16 + child: SizedBox(height: 400),
  17 + ),
  18 + ),
  19 + );
  20 + expect(tester.getSheetController().animation.value, 0);
  21 + });
  22 +
  23 + testWidgets('is 1 when starts in maxExtent', (tester) async {
  24 + await tester.pumpWidget(
  25 + MaterialApp(
  26 + home: Sheet(
  27 + minExtent: 100,
  28 + maxExtent: 400,
  29 + initialExtent: 400,
  30 + child: SizedBox(height: 400),
  31 + ),
  32 + ),
  33 + );
  34 + expect(tester.getSheetController().animation.value, 1);
  35 + });
  36 + testWidgets('is 0.5 when is between minExtent and maxExtent',
  37 + (tester) async {
  38 + await tester.pumpWidget(
  39 + MaterialApp(
  40 + home: Sheet(
  41 + minExtent: 100,
  42 + maxExtent: 300,
  43 + initialExtent: 200,
  44 + child: SizedBox(height: 300),
  45 + ),
  46 + ),
  47 + );
  48 +
  49 + expect(tester.getSheetController().animation.value, 0.5);
  50 + });
  51 +
  52 + testWidgets('is 1 when minExtent equals maxExtent', (tester) async {
  53 + await tester.pumpWidget(
  54 + MaterialApp(
  55 + home: Sheet(
  56 + minExtent: 100,
  57 + maxExtent: 100,
  58 + child: SizedBox(height: 100),
  59 + ),
  60 + ),
  61 + );
  62 + expect(tester.getSheetController().animation.value, 1);
  63 + });
  64 +
  65 + testWidgets('updates to 0 when it goes to minExtent', (tester) async {
  66 + await tester.pumpWidget(
  67 + MaterialApp(
  68 + home: Sheet(
  69 + minExtent: 100,
  70 + maxExtent: 400,
  71 + initialExtent: 400,
  72 + fit: SheetFit.expand,
  73 + child: SizedBox(),
  74 + ),
  75 + ),
  76 + );
  77 + expect(tester.getSheetController().animation.value, 1);
  78 + tester.getSheetController().relativeJumpTo(0);
  79 + await tester.pumpAndSettle();
  80 + expect(tester.getSheetController().animation.value, 0);
  81 + });
  82 +
  83 + testWidgets('updates to 1 when it goes to maxExtent', (tester) async {
  84 + await tester.pumpWidget(
  85 + MaterialApp(
  86 + home: Sheet(
  87 + minExtent: 100,
  88 + maxExtent: 400,
  89 + initialExtent: 100,
  90 + child: SizedBox(height: 400),
  91 + ),
  92 + ),
  93 + );
  94 + expect(tester.getSheetController().animation.value, 0);
  95 + tester.getSheetController().relativeJumpTo(1);
  96 + expect(tester.getSheetController().animation.value, 1);
  97 + });
  98 +
  99 + testWidgets('updates linearly', (tester) async {
  100 + await tester.pumpWidget(
  101 + MaterialApp(
  102 + home: Sheet(
  103 + minExtent: 100,
  104 + maxExtent: 300,
  105 + initialExtent: 100,
  106 + child: SizedBox(height: 300),
  107 + ),
  108 + ),
  109 + );
  110 + tester.getSheetController().relativeJumpTo(0.5);
  111 + await tester.pumpAndSettle();
  112 + expect(tester.getSheetController().animation.value, 0.5);
  113 + });
  114 + });
  115 +}
@@ -9,132 +9,184 @@ import '../screen_size_test.dart'; @@ -9,132 +9,184 @@ import '../screen_size_test.dart';
9 9
10 void main() { 10 void main() {
11 group('SheetController', () { 11 group('SheetController', () {
12 - testWidgets('jumpTo', (WidgetTester tester) async {  
13 - final GlobalKey key = GlobalKey();  
14 -  
15 - await tester.pumpApp(  
16 - Sheet(  
17 - initialExtent: 200,  
18 - child: Container(  
19 - key: key,  
20 - height: kScreenRect.height, 12 + const curve = Curves.easeInOut;
  13 + const duration = Duration(milliseconds: 1);
  14 + const child = SizedBox(height: kScreenHeight);
  15 +
  16 + group('jumpTo', () {
  17 + testWidgets('a custom extent - 400', (WidgetTester tester) async {
  18 + await tester.pumpApp(
  19 + Sheet(child: child),
  20 + );
  21 +
  22 + tester.getSheetController().jumpTo(400);
  23 + expect(tester.getSheetExtent(), 400);
  24 + });
  25 +
  26 + testWidgets('minExtent', (WidgetTester tester) async {
  27 + await tester.pumpApp(
  28 + Sheet(
  29 + minExtent: 100,
  30 + child: child,
21 ), 31 ),
22 - ),  
23 - );  
24 -  
25 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
26 - expect(tester.getSheetTop(), equals(kScreenRect.bottom - 200));  
27 -  
28 - tester.getSheetController().jumpTo(400);  
29 -  
30 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
31 - expect(tester.getSheetTop(), kScreenRect.height - 400);  
32 -  
33 - tester.getSheetController().jumpTo(-100);  
34 -  
35 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
36 - expect(tester.getSheetTop(), equals(kScreenRect.height));  
37 -  
38 - tester.getSheetController().jumpTo(kScreenRect.height + 100); 32 + );
  33 +
  34 + tester.getSheetController().jumpTo(100);
  35 + expect(tester.getSheetExtent(), 100);
  36 + });
  37 + testWidgets('maxExtent', (WidgetTester tester) async {
  38 + await tester.pumpApp(
  39 + Sheet(
  40 + maxExtent: 400,
  41 + child: child,
  42 + ),
  43 + );
  44 +
  45 + tester.getSheetController().jumpTo(400);
  46 + expect(tester.getSheetExtent(), 400);
  47 + });
  48 +
  49 + testWidgets('less than 0 clamps to 0', (WidgetTester tester) async {
  50 + await tester.pumpApp(
  51 + Sheet(child: child),
  52 + );
  53 +
  54 + tester.getSheetController().jumpTo(-100);
  55 + expect(tester.getSheetExtent(), equals(0));
  56 + });
  57 + testWidgets('less than minExtent clamps to minExtent',
  58 + (WidgetTester tester) async {
  59 + await tester.pumpApp(
  60 + Sheet(
  61 + minExtent: 100,
  62 + initialExtent: 200,
  63 + child: child,
  64 + ),
  65 + );
  66 + expect(tester.getSheetExtent(), equals(200));
  67 +
  68 + tester.getSheetController().jumpTo(100);
  69 + expect(tester.getSheetExtent(), equals(100));
  70 + });
  71 +
  72 + testWidgets(
  73 + 'more than than screenHeight clamps to screenHeight '
  74 + 'if maxExtent is null', (WidgetTester tester) async {
  75 + await tester.pumpApp(
  76 + Sheet(
  77 + child: child,
  78 + ),
  79 + );
  80 +
  81 + tester.getSheetController().jumpTo(kScreenHeight + 100);
  82 + expect(tester.getSheetExtent(), equals(kScreenHeight));
  83 + });
  84 + testWidgets('more than maxExtent clamps to maxExtent',
  85 + (WidgetTester tester) async {
  86 + await tester.pumpApp(
  87 + Sheet(
  88 + maxExtent: 400,
  89 + child: child,
  90 + ),
  91 + );
39 92
40 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
41 - expect(tester.getSheetTop(), equals(0)); 93 + tester.getSheetController().jumpTo(500);
  94 + expect(tester.getSheetExtent(), 400);
  95 + });
42 }); 96 });
43 97
44 testWidgets('relativeJumpTo', (WidgetTester tester) async { 98 testWidgets('relativeJumpTo', (WidgetTester tester) async {
45 - final GlobalKey key = GlobalKey();  
46 -  
47 await tester.pumpApp( 99 await tester.pumpApp(
48 Sheet( 100 Sheet(
49 initialExtent: 200, 101 initialExtent: 200,
50 child: Container( 102 child: Container(
51 - key: key,  
52 - height: kScreenRect.height, 103 + height: kScreenHeight,
53 ), 104 ),
54 ), 105 ),
55 ); 106 );
56 107
57 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
58 - expect(tester.getSheetTop(), equals(kScreenRect.bottom - 200)); 108 + expect(tester.getSheetExtent(), equals(200));
59 109
60 tester.getSheetController().relativeJumpTo(1); 110 tester.getSheetController().relativeJumpTo(1);
61 -  
62 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
63 - expect(tester.getSheetTop(), equals(0)); 111 + expect(tester.getSheetExtent(), equals(kScreenHeight));
64 112
65 tester.getSheetController().relativeJumpTo(0.5); 113 tester.getSheetController().relativeJumpTo(0.5);
66 -  
67 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
68 - expect(tester.getSheetTop(), equals(kScreenRect.bottom / 2)); 114 + expect(tester.getSheetExtent(), equals(kScreenHeight / 2));
69 }); 115 });
70 116
71 testWidgets('animateTo', (WidgetTester tester) async { 117 testWidgets('animateTo', (WidgetTester tester) async {
72 - final GlobalKey key = GlobalKey();  
73 -  
74 await tester.pumpApp( 118 await tester.pumpApp(
75 Sheet( 119 Sheet(
76 initialExtent: 200, 120 initialExtent: 200,
77 child: Container( 121 child: Container(
78 - key: key,  
79 - height: kScreenRect.height, 122 + height: kScreenHeight,
80 ), 123 ),
81 ), 124 ),
82 ); 125 );
83 126
84 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
85 - expect(tester.getSheetTop(), equals(kScreenRect.height - 200)); 127 + expect(tester.getSheetExtent(), equals(200));
86 128
87 - tester.getSheetController().animateTo(400,  
88 - curve: Curves.easeInOut, duration: const Duration(milliseconds: 1)); 129 + tester
  130 + .getSheetController()
  131 + .animateTo(400, curve: curve, duration: duration);
89 await tester.pumpAndSettle(); 132 await tester.pumpAndSettle();
  133 + final controller = tester.getSheetController();
  134 + expect(tester.getSheetExtent(), equals(400));
90 135
91 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
92 - expect(tester.getSheetTop(), equals(kScreenRect.bottom - 400));  
93 -  
94 - tester.getSheetController().animateTo(-100,  
95 - curve: Curves.easeInOut, duration: const Duration(milliseconds: 1)); 136 + controller.animateTo(-100, curve: curve, duration: duration);
96 await tester.pumpAndSettle(); 137 await tester.pumpAndSettle();
97 138
98 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
99 - expect(tester.getSheetTop(), equals(kScreenRect.bottom));  
100 - tester.getSheetController().animateTo(kScreenRect.height + 100,  
101 - curve: Curves.easeInOutCirc,  
102 - duration: const Duration(milliseconds: 1)); 139 + expect(tester.getSheetExtent(), equals(0));
  140 + controller.animateTo(
  141 + kScreenHeight + 100,
  142 + curve: curve,
  143 + duration: duration,
  144 + );
103 await tester.pumpAndSettle(); 145 await tester.pumpAndSettle();
104 -  
105 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
106 - expect(tester.getSheetTop(), equals(0)); 146 + expect(tester.getSheetExtent(), equals(kScreenHeight));
107 }); 147 });
108 148
109 testWidgets('relativeAnimateTo', (WidgetTester tester) async { 149 testWidgets('relativeAnimateTo', (WidgetTester tester) async {
110 - final GlobalKey key = GlobalKey();  
111 -  
112 await tester.pumpApp( 150 await tester.pumpApp(
113 Sheet( 151 Sheet(
114 initialExtent: 200, 152 initialExtent: 200,
115 child: Container( 153 child: Container(
116 - key: key,  
117 - height: kScreenRect.height, 154 + height: kScreenHeight,
118 ), 155 ),
119 ), 156 ),
120 ); 157 );
  158 + final controller = tester.getSheetController();
  159 + expect(tester.getSheetExtent(), equals(200));
121 160
122 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
123 - expect(tester.getSheetTop(), equals(kScreenRect.bottom - 200)); 161 + controller.relativeAnimateTo(1, curve: curve, duration: duration);
  162 + await tester.pumpAndSettle();
  163 + expect(tester.getSheetExtent(), equals(kScreenHeight));
124 164
125 - tester.getSheetController().relativeAnimateTo(1,  
126 - curve: Curves.easeInOut, duration: const Duration(milliseconds: 1)); 165 + controller.relativeAnimateTo(0.5, curve: curve, duration: duration);
127 await tester.pumpAndSettle(); 166 await tester.pumpAndSettle();
  167 + expect(tester.getSheetExtent(), equals(kScreenHeight * 0.5));
  168 + });
128 169
129 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
130 - expect(tester.getSheetTop(), equals(0)); 170 + testWidgets('relativeAnimateTo with min xtent',
  171 + (WidgetTester tester) async {
  172 + await tester.pumpApp(
  173 + Sheet(
  174 + initialExtent: 200,
  175 + child: Container(
  176 + height: kScreenHeight,
  177 + ),
  178 + ),
  179 + );
  180 + final controller = tester.getSheetController();
  181 + expect(tester.getSheetExtent(), equals(200));
131 182
132 - tester.getSheetController().relativeAnimateTo(0.5,  
133 - curve: Curves.easeInOut, duration: const Duration(milliseconds: 1)); 183 + controller.relativeAnimateTo(1, curve: curve, duration: duration);
134 await tester.pumpAndSettle(); 184 await tester.pumpAndSettle();
  185 + expect(tester.getSheetExtent(), equals(kScreenHeight));
135 186
136 - expect(tester.getSheetSize(), equals(kScreenRect.size));  
137 - expect(tester.getSheetTop(), equals(kScreenRect.bottom / 2)); 187 + controller.relativeAnimateTo(0.5, curve: curve, duration: duration);
  188 + await tester.pumpAndSettle();
  189 + expect(tester.getSheetExtent(), equals(kScreenHeight * 0.5));
138 }); 190 });
139 }); 191 });
140 } 192 }
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_test/flutter_test.dart';
  3 +import 'package:sheet/sheet.dart';
  4 +
  5 +import '../helpers.dart';
  6 +
  7 +void main() {
  8 + group('SheetPosition', () {
  9 + testWidgets('can prevent drag', (WidgetTester tester) async {
  10 + await tester.pumpApp(
  11 + Sheet(
  12 + child: SizedBox(height: 200),
  13 + ),
  14 + );
  15 + final position = tester.getSheetPosition();
  16 + expect(position.preventingDrag, false);
  17 + position.preventDrag();
  18 + expect(position.preventingDrag, true);
  19 + });
  20 +
  21 + testWidgets('can stops preventing drag', (WidgetTester tester) async {
  22 + await tester.pumpApp(
  23 + Sheet(
  24 + child: SizedBox(height: 200),
  25 + ),
  26 + );
  27 + final position = tester.getSheetPosition();
  28 + position.preventDrag();
  29 + expect(position.preventingDrag, true);
  30 + position.stopPreventingDrag();
  31 + expect(position.preventingDrag, false);
  32 + });
  33 + });
  34 +}
@@ -2,9 +2,9 @@ import 'package:flutter/material.dart'; @@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
2 import 'package:flutter_test/flutter_test.dart'; 2 import 'package:flutter_test/flutter_test.dart';
3 import 'package:sheet/sheet.dart'; 3 import 'package:sheet/sheet.dart';
4 4
5 -const Key _key = Key('_sheet_builder'); 5 +const Key _childKey = Key('_sheet_child');
6 6
7 -Finder findSheet() => find.byKey(_key); 7 +Finder findSheet() => find.byKey(_childKey);
8 8
9 extension SheetTester on WidgetTester { 9 extension SheetTester on WidgetTester {
10 Future<void> pumpApp(Widget sheet, {VoidCallback? onButtonPressed}) async { 10 Future<void> pumpApp(Widget sheet, {VoidCallback? onButtonPressed}) async {
@@ -41,26 +41,37 @@ extension SheetTester on WidgetTester { @@ -41,26 +41,37 @@ extension SheetTester on WidgetTester {
41 } 41 }
42 42
43 double getSheetTop() { 43 double getSheetTop() {
44 - final Offset offset = getTopLeft(find.byKey(_key)); 44 + final Offset offset = getTopLeft(find.byKey(_childKey));
45 return offset.dy; 45 return offset.dy;
46 } 46 }
47 47
  48 + double getSheetExtent() {
  49 + final Rect rootRect = getRect(find.byType(Sheet));
  50 + final Offset offset = getTopLeft(find.byKey(_childKey));
  51 + return rootRect.bottom - offset.dy;
  52 + }
  53 +
48 SheetController getSheetController() { 54 SheetController getSheetController() {
49 - final Element context = element(find.byKey(_key)); 55 + final BuildContext context = element(find.byKey(_childKey));
50 return Sheet.of(context)!.controller; 56 return Sheet.of(context)!.controller;
51 } 57 }
52 58
  59 + SheetPosition getSheetPosition() {
  60 + final BuildContext context = element(find.byKey(_childKey));
  61 + return Sheet.of(context)!.position;
  62 + }
  63 +
53 double getSheetHeight() { 64 double getSheetHeight() {
54 - final Size rect = getSize(find.byKey(_key)); 65 + final Size rect = getSize(find.byKey(_childKey));
55 return rect.height; 66 return rect.height;
56 } 67 }
57 68
58 Size getSheetSize() { 69 Size getSheetSize() {
59 - return getSize(find.byKey(_key)); 70 + return getSize(find.byKey(_childKey));
60 } 71 }
61 72
62 Future<void> dragSheet(double offset) { 73 Future<void> dragSheet(double offset) {
63 - return drag(find.byKey(_key), Offset(0, offset)); 74 + return drag(find.byKey(_childKey), Offset(0, offset));
64 } 75 }
65 } 76 }
66 77
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_test/flutter_test.dart';
  3 +import 'package:sheet/sheet.dart';
  4 +
  5 +void main() {
  6 + group('Sheet', () {
  7 + testWidgets('default has material appareance', (tester) async {
  8 + await tester.pumpWidget(
  9 + MaterialApp(
  10 + home: Sheet(
  11 + child: SizedBox(),
  12 + ),
  13 + ),
  14 + );
  15 + expect(find.byType(Material), findsOneWidget);
  16 + final material = tester.widget<Material>(find.byType(Material));
  17 + expect(
  18 + material.color,
  19 + ThemeData.fallback().bottomSheetTheme.backgroundColor,
  20 + );
  21 + });
  22 +
  23 + testWidgets('Sheet uses bottomSheetTheme by default', (tester) async {
  24 + await tester.pumpWidget(
  25 + MaterialApp(
  26 + home: Sheet(
  27 + child: SizedBox(),
  28 + ),
  29 + ),
  30 + );
  31 +
  32 + final material = tester.widget<Material>(find.byType(Material));
  33 + expect(
  34 + material.color,
  35 + ThemeData.fallback().bottomSheetTheme.backgroundColor,
  36 + );
  37 +
  38 + expect(
  39 + material.shape,
  40 + ThemeData.fallback().bottomSheetTheme.shape,
  41 + );
  42 + expect(material.elevation, 0);
  43 + expect(material.clipBehavior, Clip.none);
  44 + });
  45 +
  46 + testWidgets('.raw has no material appareance', (tester) async {
  47 + await tester.pumpWidget(
  48 + MaterialApp(
  49 + home: Sheet.raw(
  50 + child: SizedBox(),
  51 + ),
  52 + ),
  53 + );
  54 + expect(find.byType(Material), findsNothing);
  55 + });
  56 + });
  57 +}
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_test/flutter_test.dart';
  3 +import 'package:sheet/sheet.dart';
  4 +
  5 +void main() {
  6 + group('DefaultSheetController', () {
  7 + testWidgets('DefaultSheetController injects a SheetController',
  8 + (tester) async {
  9 + final childKey = UniqueKey();
  10 + await tester.pumpWidget(
  11 + MaterialApp(
  12 + home: DefaultSheetController(
  13 + child: SizedBox(key: childKey),
  14 + ),
  15 + ),
  16 + );
  17 + await tester.pumpAndSettle();
  18 + final context = tester.element(find.byKey(childKey));
  19 + expect(DefaultSheetController.of(context), isA<SheetController>());
  20 + });
  21 +
  22 + testWidgets('Sheet uses its SheetController', (tester) async {
  23 + final childKey = UniqueKey();
  24 + await tester.pumpWidget(
  25 + MaterialApp(
  26 + home: DefaultSheetController(
  27 + child: Sheet(
  28 + child: SizedBox(key: childKey),
  29 + ),
  30 + ),
  31 + ),
  32 + );
  33 + await tester.pumpAndSettle();
  34 + final context = tester.element(find.byKey(childKey));
  35 + final controller = DefaultSheetController.of(context);
  36 + expect(Sheet.of(context)!.controller, controller);
  37 + });
  38 +
  39 + testWidgets('SheetController is the same between rebuilds', (tester) async {
  40 + final childKey = UniqueKey();
  41 + late StateSetter setState;
  42 + await tester.pumpWidget(
  43 + MaterialApp(
  44 + home: StatefulBuilder(builder: (context, stateSetter) {
  45 + setState = stateSetter;
  46 + return DefaultSheetController(
  47 + child: Sheet(
  48 + child: SizedBox(key: childKey),
  49 + ),
  50 + );
  51 + }),
  52 + ),
  53 + );
  54 + await tester.pumpAndSettle();
  55 + final context = tester.element(find.byKey(childKey));
  56 + final controller = DefaultSheetController.of(context);
  57 + setState(() {});
  58 + await tester.pumpAndSettle();
  59 + expect(DefaultSheetController.of(context), controller);
  60 + });
  61 + });
  62 +}
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_test/flutter_test.dart';
  3 +import 'package:sheet/sheet.dart';
  4 +
  5 +import '../../helpers.dart';
  6 +
  7 +void main() {
  8 + group('SheetMediaQuery', () {
  9 + testWidgets('top padding is zero if sheet is not inside top safe area',
  10 + (tester) async {
  11 + final childKey = UniqueKey();
  12 + await tester.pumpWidget(
  13 + MaterialApp(
  14 + home: MediaQuery(
  15 + data: MediaQueryData(padding: EdgeInsets.only(top: 20)),
  16 + child: Sheet(
  17 + child: SheetMediaQuery(
  18 + child: SizedBox.expand(key: childKey),
  19 + ),
  20 + ),
  21 + ),
  22 + ),
  23 + );
  24 + await tester.pumpAndSettle();
  25 + final context = tester.element(find.byKey(childKey));
  26 + expect(MediaQuery.of(context).padding.top, 0);
  27 + });
  28 +
  29 + testWidgets(
  30 + 'top padding is same as top safe area if sheet is fully open '
  31 + 'before viewportDimension is rendered', (tester) async {
  32 + // viewportDimension is not available in first frame
  33 + final childKey = UniqueKey();
  34 + await tester.pumpWidget(
  35 + MaterialApp(
  36 + home: MediaQuery(
  37 + data: MediaQueryData(padding: EdgeInsets.only(top: 20)),
  38 + child: Sheet(
  39 + initialExtent: 600,
  40 + child: SheetMediaQuery(
  41 + child: SizedBox.expand(key: childKey),
  42 + ),
  43 + ),
  44 + ),
  45 + ),
  46 + );
  47 + await tester.pumpAndSettle();
  48 + final context = tester.element(find.byKey(childKey));
  49 + expect(MediaQuery.of(context).padding.top, 20);
  50 + });
  51 +
  52 + testWidgets(
  53 + 'top padding is same as top safe area if sheet is fully open '
  54 + 'after viewportDimension is rendered', (tester) async {
  55 + final childKey = UniqueKey();
  56 + await tester.pumpWidget(
  57 + MaterialApp(
  58 + home: MediaQuery(
  59 + data: MediaQueryData(padding: EdgeInsets.only(top: 20)),
  60 + child: Sheet(
  61 + child: SheetMediaQuery(
  62 + child: SizedBox.expand(key: childKey),
  63 + ),
  64 + ),
  65 + ),
  66 + ),
  67 + );
  68 + tester.getSheetController().relativeJumpTo(1);
  69 + await tester.pumpAndSettle();
  70 + final context = tester.element(find.byKey(childKey));
  71 + expect(MediaQuery.of(context).padding.top, 20);
  72 + });
  73 +
  74 + testWidgets('top padding increase is lineal', (tester) async {
  75 + final offsetToTest = 10.0;
  76 + final childKey = UniqueKey();
  77 + await tester.pumpWidget(
  78 + MaterialApp(
  79 + home: MediaQuery(
  80 + data: MediaQueryData(padding: EdgeInsets.only(top: 20)),
  81 + child: Sheet(
  82 + initialExtent: 600 - offsetToTest,
  83 + child: SizedBox(
  84 + child: SheetMediaQuery(
  85 + child: SizedBox.expand(key: childKey),
  86 + ),
  87 + ),
  88 + ),
  89 + ),
  90 + ),
  91 + );
  92 + await tester.pumpAndSettle();
  93 + final context = tester.element(find.byKey(childKey));
  94 + expect(MediaQuery.of(context).padding.top, 20 - offsetToTest);
  95 + });
  96 + });
  97 +}