diff --git a/.ci.yaml b/.ci.yaml index 4fcfc6696cc3b..9b1dff8b471c0 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -199,6 +199,8 @@ platform_properties: device_type: none windows_arm64: properties: + # The arch can be removed after https://github.com/flutter/flutter/issues/135722. + arch: arm dependencies: >- [ {"dependency": "certs", "version": "version:9563bb"} @@ -245,9 +247,12 @@ targets: task_name: analyzer_benchmark - name: Linux coverage - bringup: true + presubmit: false recipe: flutter/coverage timeout: 120 + enabled_branches: + # Don't run this on release branches + - master properties: tags: > ["framework", "hostonly", "shard", "linux"] @@ -445,6 +450,8 @@ targets: ] # TODO(flutter/flutter#123331): This device is flaking. # "--device", "model=Nexus6P,version=25", + # TODO(flutter/flutter#135784): This device is flaking. + # "--device", "model=NexusLowRes,version=29", virtual_devices: >- [ "--device", "model=Nexus5,version=21", @@ -452,8 +459,7 @@ targets: "--device", "model=Nexus5,version=23", "--device", "model=Nexus5,version=24", "--device", "model=Nexus6P,version=26", - "--device", "model=Nexus6P,version=27", - "--device", "model=NexusLowRes,version=29" + "--device", "model=Nexus6P,version=27" ] - name: Linux firebase_android_embedding_v2_smoke_test @@ -475,14 +481,15 @@ targets: ] # TODO(flutter/flutter#123331): This device is flaking. # "--device", "model=Nexus6P,version=25", + # TODO(flutter/flutter#135784): This device is flaking. + # "--device", "model=NexusLowRes,version=29", virtual_devices: >- [ "--device", "model=Nexus5,version=21", "--device", "model=Nexus5,version=22", "--device", "model=Nexus5,version=23", "--device", "model=Nexus6P,version=26", - "--device", "model=Nexus6P,version=27", - "--device", "model=NexusLowRes,version=29" + "--device", "model=Nexus6P,version=27" ] - name: Linux firebase_release_smoke_test @@ -504,14 +511,15 @@ targets: ] # TODO(flutter/flutter#123331): This device is flaking. # "--device", "model=Nexus6P,version=25", + # TODO(flutter/flutter#135784): This device is flaking. + # "--device", "model=NexusLowRes,version=29", virtual_devices: >- [ "--device", "model=Nexus5,version=21", "--device", "model=Nexus5,version=22", "--device", "model=Nexus5,version=23", "--device", "model=Nexus6P,version=26", - "--device", "model=Nexus6P,version=27", - "--device", "model=NexusLowRes,version=29" + "--device", "model=Nexus6P,version=27" ] - name: Linux flutter_packaging_test @@ -1780,7 +1788,6 @@ targets: recipe: devicelab/devicelab_drone presubmit: false # Uses Impeller. - bringup: true timeout: 60 properties: tags: > @@ -2104,7 +2111,6 @@ targets: task_name: flutter_gallery__start_up - name: Linux_android flutter_gallery__start_up_delayed - bringup: true # Flaky https://github.com/flutter/flutter/issues/134631 recipe: devicelab/devicelab_drone presubmit: false timeout: 60 @@ -2699,7 +2705,6 @@ targets: task_name: opacity_peephole_fade_transition_text_perf__e2e_summary - name: Linux_android opacity_peephole_grid_of_alpha_savelayers_perf__e2e_summary - bringup: true # Flaky https://github.com/flutter/flutter/issues/135118 recipe: devicelab/devicelab_drone presubmit: false timeout: 60 diff --git a/bin/internal/engine.version b/bin/internal/engine.version index e82ba3fb3e14d..cc7478c578172 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -0a8ad236e4afba9659831227bd4a5f8ed18d83aa +6492e1f8c3150e7f0e64dcdcd805cf575fbf8432 diff --git a/bin/internal/flutter_packages.version b/bin/internal/flutter_packages.version index 3fb150d36ffd8..f59a19182e27b 100644 --- a/bin/internal/flutter_packages.version +++ b/bin/internal/flutter_packages.version @@ -1 +1 @@ -619af75f7966f90498dfce3a754d37422b972c6d +6714d5099ad53329b0600a8b8ff6218305c74c05 diff --git a/bin/internal/fuchsia-linux.version b/bin/internal/fuchsia-linux.version index 2e0684338d2af..08ce0e29c1c57 100644 --- a/bin/internal/fuchsia-linux.version +++ b/bin/internal/fuchsia-linux.version @@ -1 +1 @@ -a56c8yPp4DDlj_QblIlLum8BoJiVSDsDsJtweyEsZ7sC +eI_FBTaRgvoBQaK5nsE0K-AujC35ZpysI402bk_1T8wC diff --git a/bin/internal/fuchsia-mac.version b/bin/internal/fuchsia-mac.version index a188d4efa073c..c98333aab11ce 100644 --- a/bin/internal/fuchsia-mac.version +++ b/bin/internal/fuchsia-mac.version @@ -1 +1 @@ -OMrTgAfDg9PKXTzq02S-SPbjInFqsBoiPrFMP-k3TNYC +th0Ks2IEZYh6fe8G5Zqu1UyM0gHL1NDidMfddpUpdl0C diff --git a/dev/a11y_assessments/pubspec.yaml b/dev/a11y_assessments/pubspec.yaml index 6d71cbeb20859..19717439b20c5 100644 --- a/dev/a11y_assessments/pubspec.yaml +++ b/dev/a11y_assessments/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -35,4 +35,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 0c69 +# PUBSPEC CHECKSUM: 176a diff --git a/dev/automated_tests/pubspec.yaml b/dev/automated_tests/pubspec.yaml index e9cac0aa1de43..0cfcdf34eeddc 100644 --- a/dev/automated_tests/pubspec.yaml +++ b/dev/automated_tests/pubspec.yaml @@ -62,7 +62,7 @@ dependencies: vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -72,4 +72,4 @@ flutter: assets: - icon/test.png -# PUBSPEC CHECKSUM: 7c7b +# PUBSPEC CHECKSUM: 127c diff --git a/dev/benchmarks/complex_layout/pubspec.yaml b/dev/benchmarks/complex_layout/pubspec.yaml index 9c768c180f9d0..770d1ee830ede 100644 --- a/dev/benchmarks/complex_layout/pubspec.yaml +++ b/dev/benchmarks/complex_layout/pubspec.yaml @@ -34,8 +34,8 @@ dependencies: test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -83,4 +83,4 @@ flutter: - packages/flutter_gallery_assets/people/square/ali.png - packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png -# PUBSPEC CHECKSUM: de52 +# PUBSPEC CHECKSUM: ed54 diff --git a/dev/benchmarks/macrobenchmarks/pubspec.yaml b/dev/benchmarks/macrobenchmarks/pubspec.yaml index 6d17bc023a845..92dcae0cc37ff 100644 --- a/dev/benchmarks/macrobenchmarks/pubspec.yaml +++ b/dev/benchmarks/macrobenchmarks/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: # flutter update-packages --force-upgrade flutter_gallery_assets: 1.0.2 - web: 0.2.1-beta + web: 0.2.2-beta async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -40,7 +40,7 @@ dependencies: test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: test: 1.24.6 @@ -210,4 +210,4 @@ flutter: fonts: - asset: packages/flutter_gallery_assets/fonts/GalleryIcons.ttf -# PUBSPEC CHECKSUM: de52 +# PUBSPEC CHECKSUM: ed54 diff --git a/dev/benchmarks/microbenchmarks/pubspec.yaml b/dev/benchmarks/microbenchmarks/pubspec.yaml index 75dee25045c26..ccb677a0dfef7 100644 --- a/dev/benchmarks/microbenchmarks/pubspec.yaml +++ b/dev/benchmarks/microbenchmarks/pubspec.yaml @@ -63,7 +63,7 @@ dependencies: vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -137,4 +137,4 @@ flutter: - packages/flutter_gallery_assets/people/square/stella.png - packages/flutter_gallery_assets/people/square/trevor.png -# PUBSPEC CHECKSUM: 1fc9 +# PUBSPEC CHECKSUM: b4ca diff --git a/dev/benchmarks/multiple_flutters/module/pubspec.yaml b/dev/benchmarks/multiple_flutters/module/pubspec.yaml index afb1401267411..e425eff1bb5e7 100644 --- a/dev/benchmarks/multiple_flutters/module/pubspec.yaml +++ b/dev/benchmarks/multiple_flutters/module/pubspec.yaml @@ -36,8 +36,8 @@ dependencies: term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - win32: 5.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + win32: 5.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xdg_directories: 1.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: @@ -48,4 +48,4 @@ flutter: androidPackage: com.example.multiple_flutters_module iosBundleIdentifier: com.example.multipleFluttersModule -# PUBSPEC CHECKSUM: 23fb +# PUBSPEC CHECKSUM: 9ffd diff --git a/dev/benchmarks/platform_channels_benchmarks/pubspec.yaml b/dev/benchmarks/platform_channels_benchmarks/pubspec.yaml index e795850a56429..b1b5684870b0d 100644 --- a/dev/benchmarks/platform_channels_benchmarks/pubspec.yaml +++ b/dev/benchmarks/platform_channels_benchmarks/pubspec.yaml @@ -64,7 +64,7 @@ dependencies: vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -74,4 +74,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 15b5 +# PUBSPEC CHECKSUM: aab6 diff --git a/dev/benchmarks/platform_views_layout/pubspec.yaml b/dev/benchmarks/platform_views_layout/pubspec.yaml index b2fed493c9570..e223c68eba006 100644 --- a/dev/benchmarks/platform_views_layout/pubspec.yaml +++ b/dev/benchmarks/platform_views_layout/pubspec.yaml @@ -34,8 +34,8 @@ dependencies: test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -81,4 +81,4 @@ flutter: - packages/flutter_gallery_assets/people/square/ali.png - packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png -# PUBSPEC CHECKSUM: de52 +# PUBSPEC CHECKSUM: ed54 diff --git a/dev/benchmarks/platform_views_layout_hybrid_composition/pubspec.yaml b/dev/benchmarks/platform_views_layout_hybrid_composition/pubspec.yaml index 7da9277564103..958be941c2fa5 100644 --- a/dev/benchmarks/platform_views_layout_hybrid_composition/pubspec.yaml +++ b/dev/benchmarks/platform_views_layout_hybrid_composition/pubspec.yaml @@ -34,8 +34,8 @@ dependencies: test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -81,4 +81,4 @@ flutter: - packages/flutter_gallery_assets/people/square/ali.png - packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png -# PUBSPEC CHECKSUM: de52 +# PUBSPEC CHECKSUM: ed54 diff --git a/dev/benchmarks/test_apps/stocks/pubspec.yaml b/dev/benchmarks/test_apps/stocks/pubspec.yaml index ac0731a83c091..b73e4fc34e2b3 100644 --- a/dev/benchmarks/test_apps/stocks/pubspec.yaml +++ b/dev/benchmarks/test_apps/stocks/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -69,11 +69,11 @@ dev_dependencies: vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: cb74 +# PUBSPEC CHECKSUM: da76 diff --git a/dev/bots/pubspec.yaml b/dev/bots/pubspec.yaml index a81f4bd8512fd..3dff7f96edb37 100644 --- a/dev/bots/pubspec.yaml +++ b/dev/bots/pubspec.yaml @@ -65,7 +65,7 @@ dependencies: typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xml: 6.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -74,4 +74,4 @@ dependencies: dev_dependencies: test_api: 0.6.1 -# PUBSPEC CHECKSUM: 86cc +# PUBSPEC CHECKSUM: 30cd diff --git a/dev/customer_testing/lib/customer_test.dart b/dev/customer_testing/lib/customer_test.dart index 3f661f1d89e28..bf2c51987abd5 100644 --- a/dev/customer_testing/lib/customer_test.dart +++ b/dev/customer_testing/lib/customer_test.dart @@ -4,6 +4,7 @@ import 'dart:io'; +import 'package:collection/collection.dart'; import 'package:meta/meta.dart'; @immutable @@ -12,58 +13,50 @@ class CustomerTest { final String errorPrefix = 'Could not parse: ${testFile.path}\n'; final List contacts = []; final List fetch = []; + final List setup = []; final List update = []; final List test = []; int? iterations; bool hasTests = false; for (final String line in testFile.readAsLinesSync().map((String line) => line.trim())) { - if (line.isEmpty) { - // blank line - } else if (line.startsWith('#')) { - // comment - } else if (line.startsWith('contact=')) { - contacts.add(line.substring(8)); - } else if (line.startsWith('fetch=')) { - fetch.add(line.substring(6)); - } else if (line.startsWith('update=')) { - update.add(Directory(line.substring(7))); - } else if (line.startsWith('iterations=')) { + if (line.isEmpty || line.startsWith('#')) { + // Blank line or comment. + continue; + } + + final bool isUnknownDirective = _TestDirective.values.firstWhereOrNull((_TestDirective d) => line.startsWith(d.name)) == null; + if (isUnknownDirective) { + throw FormatException('${errorPrefix}Unexpected directive:\n$line'); + } + + _maybeAddTestConfig(line, directive: _TestDirective.contact, directiveValues: contacts); + _maybeAddTestConfig(line, directive: _TestDirective.fetch, directiveValues: fetch); + _maybeAddTestConfig(line, directive: _TestDirective.setup, directiveValues: setup, platformAgnostic: false); + + final String updatePrefix = _directive(_TestDirective.update); + if (line.startsWith(updatePrefix)) { + update.add(Directory(line.substring(updatePrefix.length))); + } + + final String iterationsPrefix = _directive(_TestDirective.iterations); + if (line.startsWith(iterationsPrefix)) { if (iterations != null) { - throw const FormatException('Cannot specify "iterations" directive multiple times.'); + throw FormatException('Cannot specify "${_TestDirective.iterations.name}" directive multiple times.'); } - iterations = int.parse(line.substring(11)); + iterations = int.parse(line.substring(iterationsPrefix.length)); if (iterations < 1) { - throw const FormatException('The "iterations" directive must have a positive integer value.'); + throw FormatException('The "${_TestDirective.iterations.name}" directive must have a positive integer value.'); } - } else if (line.startsWith('test=')) { - hasTests = true; - test.add(line.substring(5)); - } else if (line.startsWith('test.windows=')) { - hasTests = true; - if (Platform.isWindows) { - test.add(line.substring(13)); - } - } else if (line.startsWith('test.macos=')) { - hasTests = true; - if (Platform.isMacOS) { - test.add(line.substring(11)); - } - } else if (line.startsWith('test.linux=')) { - hasTests = true; - if (Platform.isLinux) { - test.add(line.substring(11)); - } - } else if (line.startsWith('test.posix=')) { + } + + if (line.startsWith(_directive(_TestDirective.test)) || line.startsWith('${_TestDirective.test.name}.')) { hasTests = true; - if (Platform.isLinux || Platform.isMacOS) { - test.add(line.substring(11)); - } - } else { - throw FormatException('${errorPrefix}Unexpected directive:\n$line'); } + _maybeAddTestConfig(line, directive: _TestDirective.test, directiveValues: test, platformAgnostic: false); } + if (contacts.isEmpty) { - throw FormatException('${errorPrefix}No contacts specified. At least one contact e-mail address must be specified.'); + throw FormatException('${errorPrefix}No "${_TestDirective.contact.name}" directives specified. At least one contact e-mail address must be specified.'); } for (final String email in contacts) { if (!email.contains(_email) || email.endsWith('@example.com')) { @@ -71,33 +64,41 @@ class CustomerTest { } } if (fetch.isEmpty) { - throw FormatException('${errorPrefix}No "fetch" directives specified. Two lines are expected: "git clone https://github.com/USERNAME/REPOSITORY.git tests" and "git -C tests checkout HASH".'); + throw FormatException('${errorPrefix}No "${_TestDirective.fetch.name}" directives specified. Two lines are expected: "git clone https://github.com/USERNAME/REPOSITORY.git tests" and "git -C tests checkout HASH".'); } if (fetch.length < 2) { - throw FormatException('${errorPrefix}Only one "fetch" directive specified. Two lines are expected: "git clone https://github.com/USERNAME/REPOSITORY.git tests" and "git -C tests checkout HASH".'); + throw FormatException('${errorPrefix}Only one "${_TestDirective.fetch.name}" directive specified. Two lines are expected: "git clone https://github.com/USERNAME/REPOSITORY.git tests" and "git -C tests checkout HASH".'); } if (!fetch[0].contains(_fetch1)) { - throw FormatException('${errorPrefix}First "fetch" directive does not match expected pattern (expected "git clone https://github.com/USERNAME/REPOSITORY.git tests").'); + throw FormatException('${errorPrefix}First "${_TestDirective.fetch.name}" directive does not match expected pattern (expected "git clone https://github.com/USERNAME/REPOSITORY.git tests").'); } if (!fetch[1].contains(_fetch2)) { - throw FormatException('${errorPrefix}Second "fetch" directive does not match expected pattern (expected "git -C tests checkout HASH").'); + throw FormatException('${errorPrefix}Second "${_TestDirective.fetch.name}" directive does not match expected pattern (expected "git -C tests checkout HASH").'); } if (update.isEmpty) { - throw FormatException('${errorPrefix}No "update" directives specified. At least one directory must be specified. (It can be "." to just upgrade the root of the repository.)'); + throw FormatException('${errorPrefix}No "${_TestDirective.update.name}" directives specified. At least one directory must be specified. (It can be "." to just upgrade the root of the repository.)'); } if (!hasTests) { - throw FormatException('${errorPrefix}No "test" directives specified. At least one command must be specified to run tests.'); + throw FormatException('${errorPrefix}No "${_TestDirective.test.name}" directives specified. At least one command must be specified to run tests.'); } return CustomerTest._( List.unmodifiable(contacts), List.unmodifiable(fetch), + List.unmodifiable(setup), List.unmodifiable(update), List.unmodifiable(test), iterations, ); } - const CustomerTest._(this.contacts, this.fetch, this.update, this.tests, this.iterations); + const CustomerTest._( + this.contacts, + this.fetch, + this.setup, + this.update, + this.tests, + this.iterations, + ); // (e-mail regexp from HTML standard) static final RegExp _email = RegExp(r"^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"); @@ -106,7 +107,60 @@ class CustomerTest { final List contacts; final List fetch; + final List setup; final List update; final List tests; final int? iterations; + + static void _maybeAddTestConfig( + String line, { + required _TestDirective directive, + required List directiveValues, + bool platformAgnostic = true, + }) { + final List<_PlatformType> platforms = platformAgnostic + ? <_PlatformType>[_PlatformType.all] + : _PlatformType.values; + for (final _PlatformType platform in platforms) { + final String directiveName = _directive(directive, platform: platform); + if (line.startsWith(directiveName) && platform.conditionMet) { + directiveValues.add(line.substring(directiveName.length)); + } + } + } + + static String _directive( + _TestDirective directive, { + _PlatformType platform = _PlatformType.all, + }) { + return switch (platform) { + _PlatformType.all => '${directive.name}=', + _ => '${directive.name}.${platform.name}=', + }; + } +} + +enum _PlatformType { + all, + windows, + macos, + linux, + posix; + + bool get conditionMet => switch (this) { + _PlatformType.all => true, + _PlatformType.windows => Platform.isWindows, + _PlatformType.macos => Platform.isMacOS, + _PlatformType.linux => Platform.isLinux, + _PlatformType.posix => Platform.isLinux || Platform.isMacOS, + }; +} + +enum _TestDirective { + contact, + fetch, + setup, + update, + test, + iterations, } diff --git a/dev/customer_testing/lib/runner.dart b/dev/customer_testing/lib/runner.dart index 9a8b6d30bb4a7..9d25d661d5798 100644 --- a/dev/customer_testing/lib/runner.dart +++ b/dev/customer_testing/lib/runner.dart @@ -108,6 +108,21 @@ Future runTests({ } if (success) { final Directory customerRepo = Directory(path.join(checkout.path, 'tests')); + for (final String setupCommand in instructions.setup) { + if (verbose) { + print('Running setup command: $setupCommand'); + } + success = await shell( + setupCommand, + customerRepo, + verbose: verbose, + failedCallback: printHeader, + ); + if (!success) { + failure('Setup command failed: $setupCommand'); + break; + } + } for (final Directory updateDirectory in instructions.update) { final Directory resolvedUpdateDirectory = Directory(path.join(customerRepo.path, updateDirectory.path)); if (verbose) { diff --git a/dev/customer_testing/test/customer_test_test.dart b/dev/customer_testing/test/customer_test_test.dart index 129782c61d75a..b84e660f36eb2 100644 --- a/dev/customer_testing/test/customer_test_test.dart +++ b/dev/customer_testing/test/customer_test_test.dart @@ -16,6 +16,11 @@ void main() { contact=abc@gmail.com fetch=git clone https://github.com/flutter/cocoon.git tests fetch=git -C tests checkout abc123 +setup=flutter --version +setup.windows=flutter doctor +setup.posix=flutter -h +setup.linux=flutter analyze -h +setup.macos=flutter build -h update=. # Runs flutter analyze, flutter test, and builds web platform test.posix=./test_utilities/bin/flutter_test_runner.sh app_flutter @@ -30,7 +35,11 @@ test.windows=.\test_utilities\bin\flutter_test_runner.bat repo_dashboard test.fetch, containsAllInOrder( ['git clone https://github.com/flutter/cocoon.git tests', 'git -C tests checkout abc123'])); + expect(test.setup.first, 'flutter --version'); if (Platform.isLinux || Platform.isMacOS) { + expect(test.setup.length, 3); + expect(test.setup[1], 'flutter -h'); + expect(test.setup[2], Platform.isLinux ? 'flutter analyze -h' : 'flutter build -h'); expect( test.tests, containsAllInOrder([ @@ -39,6 +48,8 @@ test.windows=.\test_utilities\bin\flutter_test_runner.bat repo_dashboard ]), ); } else if (Platform.isWindows) { + expect(test.setup.length, 2); + expect(test.setup[1], 'flutter doctor'); expect(test.tests, containsAllInOrder(['.\test_utilities\bin\flutter_test_runner.bat repo_dashboard'])); } }); diff --git a/dev/devicelab/lib/framework/devices.dart b/dev/devicelab/lib/framework/devices.dart index 2720dd9689873..7ce3782664a5c 100644 --- a/dev/devicelab/lib/framework/devices.dart +++ b/dev/devicelab/lib/framework/devices.dart @@ -8,6 +8,7 @@ import 'dart:io'; import 'dart:math' as math; import 'package:path/path.dart' as path; +import 'package:retry/retry.dart'; import 'utils.dart'; @@ -193,6 +194,20 @@ abstract class Device { /// Stop a process. Future stop(String packageName); + /// Wait for the device to become ready. + Future awaitDevice(); + + Future uninstallApp() async { + await flutter('install', options: [ + '--uninstall-only', + '-d', + deviceId]); + + await Future.delayed(const Duration(seconds: 2)); + + await awaitDevice(); + } + @override String toString() { return 'device: $deviceId'; @@ -848,6 +863,23 @@ class AndroidDevice extends Device { Future reboot() { return adb(['reboot']); } + + @override + Future awaitDevice() async { + print('Waiting for device.'); + final String waitOut = await adb(['wait-for-device']); + print(waitOut); + const RetryOptions retryOptions = RetryOptions(delayFactor: Duration(seconds: 1), maxAttempts: 10, maxDelay: Duration(minutes: 1)); + await retryOptions.retry(() async { + final String adbShellOut = await adb(['shell', 'getprop sys.boot_completed']); + if (adbShellOut != '1') { + print('Device not ready.'); + print(adbShellOut); + throw const DeviceException('Phone not ready.'); + } + }, retryIf: (Exception e) => e is DeviceException); + print('Done waiting for device.'); + } } class IosDeviceDiscovery implements DeviceDiscovery { @@ -1081,6 +1113,9 @@ class IosDevice extends Device { Future reboot() { return Process.run('idevicediagnostics', ['restart', '-u', deviceId]); } + + @override + Future awaitDevice() async {} } class LinuxDevice extends Device { @@ -1133,6 +1168,9 @@ class LinuxDevice extends Device { @override Future wakeUp() async { } + + @override + Future awaitDevice() async {} } class MacosDevice extends Device { @@ -1185,6 +1223,9 @@ class MacosDevice extends Device { @override Future wakeUp() async { } + + @override + Future awaitDevice() async {} } class WindowsDevice extends Device { @@ -1237,6 +1278,9 @@ class WindowsDevice extends Device { @override Future wakeUp() async { } + + @override + Future awaitDevice() async {} } /// Fuchsia device. @@ -1291,6 +1335,9 @@ class FuchsiaDevice extends Device { Future reboot() async { // Unsupported. } + + @override + Future awaitDevice() async {} } /// Path to the `adb` executable. @@ -1366,6 +1413,9 @@ class FakeDevice extends Device { Future reboot() async { // Unsupported. } + + @override + Future awaitDevice() async {} } class FakeDeviceDiscovery implements DeviceDiscovery { @@ -1428,6 +1478,5 @@ class FakeDeviceDiscovery implements DeviceDiscovery { } @override - Future performPreflightTasks() async { - } + Future performPreflightTasks() async { } } diff --git a/dev/devicelab/lib/tasks/perf_tests.dart b/dev/devicelab/lib/tasks/perf_tests.dart index 1dc73382bfab7..9221d64a6cccd 100644 --- a/dev/devicelab/lib/tasks/perf_tests.dart +++ b/dev/devicelab/lib/tasks/perf_tests.dart @@ -958,11 +958,7 @@ class StartupTest { } } - await flutter('install', options: [ - '--uninstall-only', - '-d', - device.deviceId, - ]); + await device.uninstallApp(); } final Map averageResults = _average(results, iterations); @@ -1084,11 +1080,7 @@ class DevtoolsStartupTest { await process.exitCode; } - await flutter('install', options: [ - '--uninstall-only', - '-d', - device.deviceId, - ]); + await device.uninstallApp(); if (sawLine) { return TaskResult.success(null, benchmarkScoreKeys: []); @@ -1308,6 +1300,9 @@ class PerfTest { 'average_vsync_transitions_missed', '90th_percentile_vsync_transitions_missed', '99th_percentile_vsync_transitions_missed', + 'average_frame_request_pending_latency', + '90th_percentile_frame_request_pending_latency', + '99th_percentile_frame_request_pending_latency', if (measureCpuGpu && !isAndroid) ...[ // See https://github.com/flutter/flutter/issues/68888 if (data['average_cpu_usage'] != null) 'average_cpu_usage', @@ -1850,7 +1845,7 @@ class MemoryTest { } await adb.cancel(); - await flutter('install', options: ['--uninstall-only', '-d', device!.deviceId]); + await device!.uninstallApp(); final ListStatistics startMemoryStatistics = ListStatistics(_startMemory); final ListStatistics endMemoryStatistics = ListStatistics(_endMemory); diff --git a/dev/devicelab/pubspec.yaml b/dev/devicelab/pubspec.yaml index a3ca142e8fd5e..5395dd79a0d43 100644 --- a/dev/devicelab/pubspec.yaml +++ b/dev/devicelab/pubspec.yaml @@ -21,7 +21,7 @@ dependencies: shelf_static: 1.1.2 stack_trace: 1.11.1 vm_service: 11.10.0 - web: 0.2.1-beta + web: 0.2.2-beta webkit_inspection_protocol: 1.2.1 xml: 6.4.2 @@ -72,4 +72,4 @@ dev_dependencies: watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: c63a +# PUBSPEC CHECKSUM: 703b diff --git a/dev/devicelab/test/perf_tests_test.dart b/dev/devicelab/test/perf_tests_test.dart index 237cffb1c8013..57a214cc8b770 100644 --- a/dev/devicelab/test/perf_tests_test.dart +++ b/dev/devicelab/test/perf_tests_test.dart @@ -58,6 +58,9 @@ void main() { 'average_vsync_transitions_missed': 1, '90th_percentile_vsync_transitions_missed': 1, '99th_percentile_vsync_transitions_missed': 1, + 'average_frame_request_pending_latency': 0.1, + '90th_percentile_frame_request_pending_latency': 0.1, + '99th_percentile_frame_request_pending_latency': 0.1, }; const String resultFileName = 'fake_result'; void driveCallback(List arguments) { @@ -108,6 +111,9 @@ void main() { '90hz_frame_percentage': 0.4, '120hz_frame_percentage': 0.6, 'illegal_refresh_rate_frame_count': 10, + 'average_frame_request_pending_latency': 0.1, + '90th_percentile_frame_request_pending_latency': 0.1, + '99th_percentile_frame_request_pending_latency': 0.1, }; const String resultFileName = 'fake_result'; void driveCallback(List arguments) { diff --git a/dev/integration_tests/abstract_method_smoke_test/pubspec.yaml b/dev/integration_tests/abstract_method_smoke_test/pubspec.yaml index 3dd766b495c37..f9a180a18c782 100644 --- a/dev/integration_tests/abstract_method_smoke_test/pubspec.yaml +++ b/dev/integration_tests/abstract_method_smoke_test/pubspec.yaml @@ -15,9 +15,9 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 0ae4 +# PUBSPEC CHECKSUM: 15e5 diff --git a/dev/integration_tests/android_embedding_v2_smoke_test/pubspec.yaml b/dev/integration_tests/android_embedding_v2_smoke_test/pubspec.yaml index db54176660212..9b9d4291cbaf0 100644 --- a/dev/integration_tests/android_embedding_v2_smoke_test/pubspec.yaml +++ b/dev/integration_tests/android_embedding_v2_smoke_test/pubspec.yaml @@ -34,7 +34,7 @@ dependencies: meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin_platform_interface: 2.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -96,4 +96,4 @@ flutter: # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages -# PUBSPEC CHECKSUM: 103e +# PUBSPEC CHECKSUM: 1b3f diff --git a/dev/integration_tests/android_semantics_testing/pubspec.yaml b/dev/integration_tests/android_semantics_testing/pubspec.yaml index 672ac5a2c26ea..83dbd0ce9220e 100644 --- a/dev/integration_tests/android_semantics_testing/pubspec.yaml +++ b/dev/integration_tests/android_semantics_testing/pubspec.yaml @@ -58,7 +58,7 @@ dependencies: vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -66,4 +66,4 @@ dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: a372 +# PUBSPEC CHECKSUM: 3973 diff --git a/dev/integration_tests/android_views/pubspec.yaml b/dev/integration_tests/android_views/pubspec.yaml index 16e4bb7ac4f7d..991405ff7609e 100644 --- a/dev/integration_tests/android_views/pubspec.yaml +++ b/dev/integration_tests/android_views/pubspec.yaml @@ -46,9 +46,9 @@ dependencies: test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - win32: 5.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + win32: 5.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xdg_directories: 1.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: @@ -92,4 +92,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: aeb0 +# PUBSPEC CHECKSUM: 89b3 diff --git a/dev/integration_tests/channels/pubspec.yaml b/dev/integration_tests/channels/pubspec.yaml index cc9c8a637bc84..9165f25651837 100644 --- a/dev/integration_tests/channels/pubspec.yaml +++ b/dev/integration_tests/channels/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: integration_test: @@ -38,9 +38,9 @@ dev_dependencies: term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: e584 +# PUBSPEC CHECKSUM: 1286 diff --git a/dev/integration_tests/deferred_components_test/pubspec.yaml b/dev/integration_tests/deferred_components_test/pubspec.yaml index d6eb5693b0e49..7e19dd5837e1a 100644 --- a/dev/integration_tests/deferred_components_test/pubspec.yaml +++ b/dev/integration_tests/deferred_components_test/pubspec.yaml @@ -29,8 +29,8 @@ dependencies: test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -80,4 +80,4 @@ flutter: assets: - customassets/flutter_logo.png -# PUBSPEC CHECKSUM: 9fb7 +# PUBSPEC CHECKSUM: aeb9 diff --git a/dev/integration_tests/external_ui/pubspec.yaml b/dev/integration_tests/external_ui/pubspec.yaml index a6a5107e46531..c8e734f6fb113 100644 --- a/dev/integration_tests/external_ui/pubspec.yaml +++ b/dev/integration_tests/external_ui/pubspec.yaml @@ -56,13 +56,13 @@ dependencies: vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: ebfa +# PUBSPEC CHECKSUM: fafc diff --git a/dev/integration_tests/flavors/integration_test/integration_test.dart b/dev/integration_tests/flavors/integration_test/integration_test.dart index d2cdd10dd4ec9..4fda3ce79bb4c 100644 --- a/dev/integration_tests/flavors/integration_test/integration_test.dart +++ b/dev/integration_tests/flavors/integration_test/integration_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:flavors/main.dart' as app; +import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; @@ -16,6 +17,7 @@ void main() { await tester.pumpAndSettle(); expect(find.text('paid'), findsOneWidget); + expect(appFlavor, 'paid'); }); }); } diff --git a/dev/integration_tests/flavors/pubspec.yaml b/dev/integration_tests/flavors/pubspec.yaml index c67b1791e4d41..acd5a36944735 100644 --- a/dev/integration_tests/flavors/pubspec.yaml +++ b/dev/integration_tests/flavors/pubspec.yaml @@ -58,9 +58,9 @@ dependencies: vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -74,4 +74,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 9fb7 +# PUBSPEC CHECKSUM: aeb9 diff --git a/dev/integration_tests/flutter_gallery/pubspec.yaml b/dev/integration_tests/flutter_gallery/pubspec.yaml index 1fc8421f36c5a..5624971fb5268 100644 --- a/dev/integration_tests/flutter_gallery/pubspec.yaml +++ b/dev/integration_tests/flutter_gallery/pubspec.yaml @@ -49,7 +49,7 @@ dependencies: vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" video_player_platform_interface: 5.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" video_player_web: 2.0.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -102,7 +102,7 @@ dev_dependencies: vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -276,4 +276,4 @@ flutter: - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Regular.ttf - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Light.ttf -# PUBSPEC CHECKSUM: fd6b +# PUBSPEC CHECKSUM: 0d6d diff --git a/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml b/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml index ffabcfd441507..6fdec41b9f020 100644 --- a/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml +++ b/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml @@ -11,8 +11,8 @@ dependencies: async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - camera_android: 0.10.8+9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - camera_avfoundation: 0.9.13+5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + camera_android: 0.10.8+12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + camera_avfoundation: 0.9.13+6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" camera_platform_interface: 2.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" camera_web: 0.3.2+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -34,9 +34,9 @@ dependencies: term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 0937 +# PUBSPEC CHECKSUM: f063 diff --git a/dev/integration_tests/hybrid_android_views/pubspec.yaml b/dev/integration_tests/hybrid_android_views/pubspec.yaml index c471c69ebcb92..ae511c032f658 100644 --- a/dev/integration_tests/hybrid_android_views/pubspec.yaml +++ b/dev/integration_tests/hybrid_android_views/pubspec.yaml @@ -44,9 +44,9 @@ dependencies: test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - win32: 5.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + win32: 5.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xdg_directories: 1.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: @@ -90,4 +90,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: aeb0 +# PUBSPEC CHECKSUM: 89b3 diff --git a/dev/integration_tests/ios_add2app_life_cycle/flutterapp/pubspec.yaml b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/pubspec.yaml index f1fbc13f76144..60e966f0406aa 100644 --- a/dev/integration_tests/ios_add2app_life_cycle/flutterapp/pubspec.yaml +++ b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/pubspec.yaml @@ -29,7 +29,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -99,4 +99,4 @@ flutter: androidPackage: com.example.iosadd2appflutter iosBundleIdentifier: com.example.iosAdd2appFlutter -# PUBSPEC CHECKSUM: 4112 +# PUBSPEC CHECKSUM: 4c13 diff --git a/dev/integration_tests/ios_app_with_extensions/pubspec.yaml b/dev/integration_tests/ios_app_with_extensions/pubspec.yaml index 94a23a2b992a7..fbae83ef782d8 100644 --- a/dev/integration_tests/ios_app_with_extensions/pubspec.yaml +++ b/dev/integration_tests/ios_app_with_extensions/pubspec.yaml @@ -29,7 +29,7 @@ dependencies: meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin_platform_interface: 2.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -91,4 +91,4 @@ flutter: # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages -# PUBSPEC CHECKSUM: 8498 +# PUBSPEC CHECKSUM: 8f99 diff --git a/dev/integration_tests/ios_platform_view_tests/pubspec.yaml b/dev/integration_tests/ios_platform_view_tests/pubspec.yaml index 19fd1544729ca..67d028e39d72a 100644 --- a/dev/integration_tests/ios_platform_view_tests/pubspec.yaml +++ b/dev/integration_tests/ios_platform_view_tests/pubspec.yaml @@ -29,8 +29,8 @@ dependencies: test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -77,4 +77,4 @@ flutter: # the material Icons class. uses-material-design: true -# PUBSPEC CHECKSUM: 9fb7 +# PUBSPEC CHECKSUM: aeb9 diff --git a/dev/integration_tests/non_nullable/pubspec.yaml b/dev/integration_tests/non_nullable/pubspec.yaml index 9d9ff91c3c002..54db6bca4f3a7 100644 --- a/dev/integration_tests/non_nullable/pubspec.yaml +++ b/dev/integration_tests/non_nullable/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -39,4 +39,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 4112 +# PUBSPEC CHECKSUM: 4c13 diff --git a/dev/integration_tests/platform_interaction/pubspec.yaml b/dev/integration_tests/platform_interaction/pubspec.yaml index 303ccd4b08b5e..9e9dc6291c793 100644 --- a/dev/integration_tests/platform_interaction/pubspec.yaml +++ b/dev/integration_tests/platform_interaction/pubspec.yaml @@ -56,13 +56,13 @@ dependencies: vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: ebfa +# PUBSPEC CHECKSUM: fafc diff --git a/dev/integration_tests/release_smoke_test/pubspec.yaml b/dev/integration_tests/release_smoke_test/pubspec.yaml index 5e7915978095f..d81a4d16e9a92 100644 --- a/dev/integration_tests/release_smoke_test/pubspec.yaml +++ b/dev/integration_tests/release_smoke_test/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -34,4 +34,4 @@ dev_dependencies: test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 474b +# PUBSPEC CHECKSUM: 524c diff --git a/dev/integration_tests/spell_check/pubspec.yaml b/dev/integration_tests/spell_check/pubspec.yaml index e12b8bb8255eb..93fe1ff1dc965 100644 --- a/dev/integration_tests/spell_check/pubspec.yaml +++ b/dev/integration_tests/spell_check/pubspec.yaml @@ -39,7 +39,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -106,4 +106,4 @@ flutter: # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages -# PUBSPEC CHECKSUM: 85f3 +# PUBSPEC CHECKSUM: 90f4 diff --git a/dev/integration_tests/ui/pubspec.yaml b/dev/integration_tests/ui/pubspec.yaml index 27ceab81fa333..c906eab78f1d1 100644 --- a/dev/integration_tests/ui/pubspec.yaml +++ b/dev/integration_tests/ui/pubspec.yaml @@ -57,9 +57,9 @@ dependencies: vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -76,4 +76,4 @@ flutter: assets: - assets/foo.png -# PUBSPEC CHECKSUM: 9fb7 +# PUBSPEC CHECKSUM: aeb9 diff --git a/dev/integration_tests/web/pubspec.yaml b/dev/integration_tests/web/pubspec.yaml index 55d8197a797e1..be48a8f292a30 100644 --- a/dev/integration_tests/web/pubspec.yaml +++ b/dev/integration_tests/web/pubspec.yaml @@ -19,6 +19,6 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 0ae4 +# PUBSPEC CHECKSUM: 15e5 diff --git a/dev/integration_tests/web_compile_tests/pubspec.yaml b/dev/integration_tests/web_compile_tests/pubspec.yaml index 10c74337b573f..ff1c6958b0e9a 100644 --- a/dev/integration_tests/web_compile_tests/pubspec.yaml +++ b/dev/integration_tests/web_compile_tests/pubspec.yaml @@ -11,6 +11,6 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 0ae4 +# PUBSPEC CHECKSUM: 15e5 diff --git a/dev/integration_tests/web_e2e_tests/pubspec.yaml b/dev/integration_tests/web_e2e_tests/pubspec.yaml index a8fdd163c0366..5e795f2ddd652 100644 --- a/dev/integration_tests/web_e2e_tests/pubspec.yaml +++ b/dev/integration_tests/web_e2e_tests/pubspec.yaml @@ -42,8 +42,8 @@ dependencies: test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_goldens: @@ -84,4 +84,4 @@ dev_dependencies: webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 1d9e +# PUBSPEC CHECKSUM: 2ca0 diff --git a/dev/integration_tests/wide_gamut_test/pubspec.yaml b/dev/integration_tests/wide_gamut_test/pubspec.yaml index b86f9c131a842..c63e2a8f37fec 100644 --- a/dev/integration_tests/wide_gamut_test/pubspec.yaml +++ b/dev/integration_tests/wide_gamut_test/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -41,4 +41,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 474b +# PUBSPEC CHECKSUM: 524c diff --git a/dev/integration_tests/windows_startup_test/pubspec.yaml b/dev/integration_tests/windows_startup_test/pubspec.yaml index 2cfd559220870..17c752d199db3 100644 --- a/dev/integration_tests/windows_startup_test/pubspec.yaml +++ b/dev/integration_tests/windows_startup_test/pubspec.yaml @@ -56,10 +56,10 @@ dependencies: vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: ebfa +# PUBSPEC CHECKSUM: fafc diff --git a/dev/manual_tests/pubspec.yaml b/dev/manual_tests/pubspec.yaml index 8c3a81f6230e8..f1a827d8d6ea7 100644 --- a/dev/manual_tests/pubspec.yaml +++ b/dev/manual_tests/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -34,4 +34,4 @@ dev_dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 0c69 +# PUBSPEC CHECKSUM: 176a diff --git a/dev/tools/vitool/pubspec.yaml b/dev/tools/vitool/pubspec.yaml index 2c3b726e05933..19bc01545a233 100644 --- a/dev/tools/vitool/pubspec.yaml +++ b/dev/tools/vitool/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" petitparser: 6.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -37,4 +37,4 @@ dev_dependencies: term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 3f13 +# PUBSPEC CHECKSUM: 5e14 diff --git a/dev/tracing_tests/pubspec.yaml b/dev/tracing_tests/pubspec.yaml index 9fa6a4e0af07d..9508905c9aaaf 100644 --- a/dev/tracing_tests/pubspec.yaml +++ b/dev/tracing_tests/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -34,4 +34,4 @@ dev_dependencies: term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 474b +# PUBSPEC CHECKSUM: 524c diff --git a/examples/api/pubspec.yaml b/examples/api/pubspec.yaml index 42a25c17013b8..08f7d31b628c3 100644 --- a/examples/api/pubspec.yaml +++ b/examples/api/pubspec.yaml @@ -20,7 +20,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: integration_test: @@ -83,11 +83,11 @@ dev_dependencies: vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 2aa3 +# PUBSPEC CHECKSUM: 39a5 diff --git a/examples/api/test/material/context_menu/selectable_region_toolbar_builder.0_test.dart b/examples/api/test/material/context_menu/selectable_region_toolbar_builder.0_test.dart index 31b89ee89dd03..a7147873fbe4a 100644 --- a/examples/api/test/material/context_menu/selectable_region_toolbar_builder.0_test.dart +++ b/examples/api/test/material/context_menu/selectable_region_toolbar_builder.0_test.dart @@ -24,6 +24,9 @@ void main() { // Right clicking the Text in the SelectionArea shows the custom context // menu. + final TestGesture primaryMouseButtonGesture = await tester.createGesture( + kind: PointerDeviceKind.mouse, + ); final TestGesture gesture = await tester.startGesture( tester.getCenter(find.text(example.text)), kind: PointerDeviceKind.mouse, @@ -37,7 +40,9 @@ void main() { expect(find.text('Print'), findsOneWidget); // Tap to dismiss. - await tester.tapAt(tester.getCenter(find.byType(Scaffold))); + await primaryMouseButtonGesture.down(tester.getCenter(find.byType(Scaffold))); + await tester.pump(); + await primaryMouseButtonGesture.up(); await tester.pumpAndSettle(); expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing); diff --git a/examples/flutter_view/pubspec.yaml b/examples/flutter_view/pubspec.yaml index ce118d5f8fd8b..ffd01d701399a 100644 --- a/examples/flutter_view/pubspec.yaml +++ b/examples/flutter_view/pubspec.yaml @@ -13,11 +13,11 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true assets: - assets/flutter-mark-square-64.png -# PUBSPEC CHECKSUM: 0ae4 +# PUBSPEC CHECKSUM: 15e5 diff --git a/examples/hello_world/pubspec.yaml b/examples/hello_world/pubspec.yaml index 1c4bdbd16f182..13787807f4945 100644 --- a/examples/hello_world/pubspec.yaml +++ b/examples/hello_world/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_driver: @@ -64,8 +64,8 @@ dev_dependencies: vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 9fb7 +# PUBSPEC CHECKSUM: aeb9 diff --git a/examples/image_list/pubspec.yaml b/examples/image_list/pubspec.yaml index 9e5f4dab6d65a..0fd6feb5b4363 100644 --- a/examples/image_list/pubspec.yaml +++ b/examples/image_list/pubspec.yaml @@ -19,7 +19,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -54,4 +54,4 @@ flutter: assets: - images/coast.jpg -# PUBSPEC CHECKSUM: 4112 +# PUBSPEC CHECKSUM: 4c13 diff --git a/examples/layers/pubspec.yaml b/examples/layers/pubspec.yaml index d82f2d649cd5e..d05bdb6695550 100644 --- a/examples/layers/pubspec.yaml +++ b/examples/layers/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -36,4 +36,4 @@ flutter: - services/data.json uses-material-design: true -# PUBSPEC CHECKSUM: 0c69 +# PUBSPEC CHECKSUM: 176a diff --git a/examples/platform_channel/pubspec.yaml b/examples/platform_channel/pubspec.yaml index 8081c270ef527..cd6c14456b11e 100644 --- a/examples/platform_channel/pubspec.yaml +++ b/examples/platform_channel/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -64,11 +64,11 @@ dev_dependencies: vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 9fb7 +# PUBSPEC CHECKSUM: aeb9 diff --git a/examples/platform_channel_swift/pubspec.yaml b/examples/platform_channel_swift/pubspec.yaml index 34a5a2bbc5200..987151a0cb22c 100644 --- a/examples/platform_channel_swift/pubspec.yaml +++ b/examples/platform_channel_swift/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -64,11 +64,11 @@ dev_dependencies: vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 9fb7 +# PUBSPEC CHECKSUM: aeb9 diff --git a/examples/platform_view/pubspec.yaml b/examples/platform_view/pubspec.yaml index 1f512b1561296..b3b0be95af542 100644 --- a/examples/platform_view/pubspec.yaml +++ b/examples/platform_view/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: @@ -20,4 +20,4 @@ flutter: assets: - assets/flutter-mark-square-64.png -# PUBSPEC CHECKSUM: 0ae4 +# PUBSPEC CHECKSUM: 15e5 diff --git a/examples/splash/pubspec.yaml b/examples/splash/pubspec.yaml index f87573007a315..3b271765846bc 100644 --- a/examples/splash/pubspec.yaml +++ b/examples/splash/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -31,4 +31,4 @@ dev_dependencies: term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 0c69 +# PUBSPEC CHECKSUM: 176a diff --git a/examples/texture/pubspec.yaml b/examples/texture/pubspec.yaml index 726bfb44501dd..c88804a4bcb7f 100644 --- a/examples/texture/pubspec.yaml +++ b/examples/texture/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -64,4 +64,4 @@ dev_dependencies: webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: a372 +# PUBSPEC CHECKSUM: 3973 diff --git a/packages/flutter/lib/services.dart b/packages/flutter/lib/services.dart index 9cfde5e909806..cdd209fd1f8bb 100644 --- a/packages/flutter/lib/services.dart +++ b/packages/flutter/lib/services.dart @@ -19,6 +19,7 @@ export 'src/services/browser_context_menu.dart'; export 'src/services/clipboard.dart'; export 'src/services/debug.dart'; export 'src/services/deferred_component.dart'; +export 'src/services/flavor.dart'; export 'src/services/font_loader.dart'; export 'src/services/haptic_feedback.dart'; export 'src/services/hardware_keyboard.dart'; diff --git a/packages/flutter/lib/src/cupertino/picker.dart b/packages/flutter/lib/src/cupertino/picker.dart index ecbce297b9115..78f8fc4322230 100644 --- a/packages/flutter/lib/src/cupertino/picker.dart +++ b/packages/flutter/lib/src/cupertino/picker.dart @@ -49,7 +49,7 @@ const double _kOverAndUnderCenterOpacity = 0.447; /// /// * [ListWheelScrollView], the generic widget backing this picker without /// the iOS design specific chrome. -/// * +/// * class CupertinoPicker extends StatefulWidget { /// Creates a picker from a concrete list of children. /// diff --git a/packages/flutter/lib/src/material/input_decorator.dart b/packages/flutter/lib/src/material/input_decorator.dart index e429eb8e7740c..80091f426444f 100644 --- a/packages/flutter/lib/src/material/input_decorator.dart +++ b/packages/flutter/lib/src/material/input_decorator.dart @@ -2903,7 +2903,6 @@ class InputDecoration { /// {@endtemplate} final TextStyle? errorStyle; - /// The maximum number of lines the [errorText] can occupy. /// /// Defaults to null, which means that the [errorText] will be limited diff --git a/packages/flutter/lib/src/material/navigation_bar.dart b/packages/flutter/lib/src/material/navigation_bar.dart index c6c99e40d8348..b209ffb21ec04 100644 --- a/packages/flutter/lib/src/material/navigation_bar.dart +++ b/packages/flutter/lib/src/material/navigation_bar.dart @@ -295,6 +295,7 @@ class NavigationDestination extends StatelessWidget { this.selectedIcon, required this.label, this.tooltip, + this.enabled = true, }); /// The [Widget] (usually an [Icon]) that's displayed for this @@ -333,11 +334,17 @@ class NavigationDestination extends StatelessWidget { /// Defaults to null, in which case the [label] text will be used. final String? tooltip; + /// Indicates that this destination is selectable. + /// + /// Defaults to true. + final bool enabled; + @override Widget build(BuildContext context) { final _NavigationDestinationInfo info = _NavigationDestinationInfo.of(context); const Set selectedState = {MaterialState.selected}; const Set unselectedState = {}; + const Set disabledState = {MaterialState.disabled}; final NavigationBarThemeData navigationBarTheme = NavigationBarTheme.of(context); final NavigationBarThemeData defaults = _defaultsFor(context); @@ -346,15 +353,24 @@ class NavigationDestination extends StatelessWidget { return _NavigationDestinationBuilder( label: label, tooltip: tooltip, + enabled: enabled, buildIcon: (BuildContext context) { + final IconThemeData selectedIconTheme = + navigationBarTheme.iconTheme?.resolve(selectedState) + ?? defaults.iconTheme!.resolve(selectedState)!; + final IconThemeData unselectedIconTheme = + navigationBarTheme.iconTheme?.resolve(unselectedState) + ?? defaults.iconTheme!.resolve(unselectedState)!; + final IconThemeData disabledIconTheme = + navigationBarTheme.iconTheme?.resolve(disabledState) + ?? defaults.iconTheme!.resolve(disabledState)!; + final Widget selectedIconWidget = IconTheme.merge( - data: navigationBarTheme.iconTheme?.resolve(selectedState) - ?? defaults.iconTheme!.resolve(selectedState)!, + data: enabled ? selectedIconTheme : disabledIconTheme, child: selectedIcon ?? icon, ); final Widget unselectedIconWidget = IconTheme.merge( - data: navigationBarTheme.iconTheme?.resolve(unselectedState) - ?? defaults.iconTheme!.resolve(unselectedState)!, + data: enabled ? unselectedIconTheme : disabledIconTheme, child: icon, ); @@ -382,7 +398,15 @@ class NavigationDestination extends StatelessWidget { ?? defaults.labelTextStyle!.resolve(selectedState); final TextStyle? effectiveUnselectedLabelTextStyle = navigationBarTheme.labelTextStyle?.resolve(unselectedState) ?? defaults.labelTextStyle!.resolve(unselectedState); - final TextStyle? textStyle = _isForwardOrCompleted(animation) ? effectiveSelectedLabelTextStyle : effectiveUnselectedLabelTextStyle; + final TextStyle? effectiveDisabledLabelTextStyle = navigationBarTheme.labelTextStyle?.resolve(disabledState) + ?? defaults.labelTextStyle!.resolve(disabledState); + + final TextStyle? textStyle = enabled + ? _isForwardOrCompleted(animation) + ? effectiveSelectedLabelTextStyle + : effectiveUnselectedLabelTextStyle + : effectiveDisabledLabelTextStyle; + return Padding( padding: const EdgeInsets.only(top: 4), child: MediaQuery.withClampedTextScaling( @@ -416,6 +440,7 @@ class _NavigationDestinationBuilder extends StatefulWidget { required this.buildLabel, required this.label, this.tooltip, + this.enabled = true, }); /// Builds the icon for a destination in a [NavigationBar]. @@ -454,6 +479,11 @@ class _NavigationDestinationBuilder extends StatefulWidget { /// Defaults to null, in which case the [label] text will be used. final String? tooltip; + /// Indicates that this destination is selectable. + /// + /// Defaults to true. + final bool enabled; + @override State<_NavigationDestinationBuilder> createState() => _NavigationDestinationBuilderState(); } @@ -474,7 +504,7 @@ class _NavigationDestinationBuilderState extends State<_NavigationDestinationBui iconKey: iconKey, labelBehavior: info.labelBehavior, customBorder: navigationBarTheme.indicatorShape ?? defaults.indicatorShape, - onTap: info.onTap, + onTap: widget.enabled ? info.onTap : null, child: Row( children: [ Expanded( @@ -1319,9 +1349,11 @@ class _NavigationBarDefaultsM3 extends NavigationBarThemeData { return MaterialStateProperty.resolveWith((Set states) { return IconThemeData( size: 24.0, - color: states.contains(MaterialState.selected) - ? _colors.onSecondaryContainer - : _colors.onSurfaceVariant, + color: states.contains(MaterialState.disabled) + ? _colors.onSurfaceVariant.withOpacity(0.38) + : states.contains(MaterialState.selected) + ? _colors.onSecondaryContainer + : _colors.onSurfaceVariant, ); }); } @@ -1332,9 +1364,11 @@ class _NavigationBarDefaultsM3 extends NavigationBarThemeData { @override MaterialStateProperty? get labelTextStyle { return MaterialStateProperty.resolveWith((Set states) { final TextStyle style = _textTheme.labelMedium!; - return style.apply(color: states.contains(MaterialState.selected) - ? _colors.onSurface - : _colors.onSurfaceVariant + return style.apply(color: states.contains(MaterialState.disabled) + ? _colors.onSurfaceVariant.withOpacity(0.38) + : states.contains(MaterialState.selected) + ? _colors.onSurface + : _colors.onSurfaceVariant ); }); } diff --git a/packages/flutter/lib/src/material/progress_indicator.dart b/packages/flutter/lib/src/material/progress_indicator.dart index 8dc13967c147b..2a1cfa80e8f53 100644 --- a/packages/flutter/lib/src/material/progress_indicator.dart +++ b/packages/flutter/lib/src/material/progress_indicator.dart @@ -865,8 +865,21 @@ class RefreshProgressIndicator extends CircularProgressIndicator { super.semanticsLabel, super.semanticsValue, super.strokeCap, + this.elevation = 2.0, + this.indicatorMargin = const EdgeInsets.all(4.0), + this.indicatorPadding = const EdgeInsets.all(12.0), }); + /// {@macro flutter.material.material.elevation} + final double elevation; + + /// The amount of space by which to inset the whole indicator. + /// It accommodates the [elevation] of the indicator. + final EdgeInsetsGeometry indicatorMargin; + + /// The amount of space by which to inset the inner refresh indicator. + final EdgeInsetsGeometry indicatorPadding; + /// Default stroke width. static const double defaultStrokeWidth = 2.5; @@ -913,6 +926,10 @@ class _RefreshProgressIndicatorState extends _CircularProgressIndicatorState { // Last value received from the widget before null. double? _lastValue; + /// Force casting the widget as [RefreshProgressIndicator]. + @override + RefreshProgressIndicator get widget => super.widget as RefreshProgressIndicator; + // Always show the indeterminate version of the circular progress indicator. // // When value is non-null the sweep of the progress indicator arrow's arc @@ -973,13 +990,13 @@ class _RefreshProgressIndicatorState extends _CircularProgressIndicatorState { child: Container( width: _indicatorSize, height: _indicatorSize, - margin: const EdgeInsets.all(4.0), // accommodate the shadow + margin: widget.indicatorMargin, child: Material( type: MaterialType.circle, color: backgroundColor, - elevation: 2.0, + elevation: widget.elevation, child: Padding( - padding: const EdgeInsets.all(12.0), + padding: widget.indicatorPadding, child: Opacity( opacity: opacity, child: Transform.rotate( diff --git a/packages/flutter/lib/src/material/range_slider.dart b/packages/flutter/lib/src/material/range_slider.dart index af73161d2a4d1..d8bb4961f1148 100644 --- a/packages/flutter/lib/src/material/range_slider.dart +++ b/packages/flutter/lib/src/material/range_slider.dart @@ -900,8 +900,8 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix late TapGestureRecognizer _tap; bool _active = false; late RangeValues _newValues; - late Offset _startThumbCenter; - late Offset _endThumbCenter; + Offset _startThumbCenter = Offset.zero; + Offset _endThumbCenter = Offset.zero; Rect? overlayStartRect; Rect? overlayEndRect; diff --git a/packages/flutter/lib/src/material/search_anchor.dart b/packages/flutter/lib/src/material/search_anchor.dart index 1c68a4fd8496f..32fcad2862a76 100644 --- a/packages/flutter/lib/src/material/search_anchor.dart +++ b/packages/flutter/lib/src/material/search_anchor.dart @@ -342,7 +342,8 @@ class _SearchAnchorState extends State { } void _openView() { - Navigator.of(context).push(_SearchViewRoute( + final NavigatorState navigator = Navigator.of(context); + navigator.push(_SearchViewRoute( viewLeading: widget.viewLeading, viewTrailing: widget.viewTrailing, viewHintText: widget.viewHintText, @@ -363,6 +364,7 @@ class _SearchAnchorState extends State { searchController: _searchController, suggestionsBuilder: widget.suggestionsBuilder, textCapitalization: widget.textCapitalization, + capturedThemes: InheritedTheme.capture(from: context, to: navigator.context), )); } @@ -433,6 +435,7 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> { required this.anchorKey, required this.searchController, required this.suggestionsBuilder, + required this.capturedThemes, }); final ValueGetter? toggleVisibility; @@ -455,6 +458,7 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> { final GlobalKey anchorKey; final SearchController searchController; final SuggestionsBuilder suggestionsBuilder; + final CapturedThemes capturedThemes; @override Color? get barrierColor => Colors.transparent; @@ -467,7 +471,6 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> { late final SearchViewThemeData viewDefaults; late final SearchViewThemeData viewTheme; - late final DividerThemeData dividerTheme; final RectTween _rectTween = RectTween(); Rect? getRect() { @@ -502,7 +505,6 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> { void updateViewConfig(BuildContext context) { viewDefaults = _SearchViewDefaultsM3(context, isFullScreen: showFullScreenView); viewTheme = SearchViewTheme.of(context); - dividerTheme = DividerTheme.of(context); } void updateTweens(BuildContext context) { @@ -576,30 +578,29 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> { curve: _kViewFadeOnInterval, reverseCurve: _kViewFadeOnInterval.flipped, ), - child: _ViewContent( - viewLeading: viewLeading, - viewTrailing: viewTrailing, - viewHintText: viewHintText, - viewBackgroundColor: viewBackgroundColor, - viewElevation: viewElevation, - viewSurfaceTintColor: viewSurfaceTintColor, - viewSide: viewSide, - viewShape: viewShape, - viewHeaderTextStyle: viewHeaderTextStyle, - viewHeaderHintStyle: viewHeaderHintStyle, - dividerColor: dividerColor, - showFullScreenView: showFullScreenView, - animation: curvedAnimation, - topPadding: topPadding, - viewMaxWidth: _rectTween.end!.width, - viewRect: viewRect, - viewDefaults: viewDefaults, - viewTheme: viewTheme, - dividerTheme: dividerTheme, - viewBuilder: viewBuilder, - searchController: searchController, - suggestionsBuilder: suggestionsBuilder, - textCapitalization: textCapitalization, + child: capturedThemes.wrap( + _ViewContent( + viewLeading: viewLeading, + viewTrailing: viewTrailing, + viewHintText: viewHintText, + viewBackgroundColor: viewBackgroundColor, + viewElevation: viewElevation, + viewSurfaceTintColor: viewSurfaceTintColor, + viewSide: viewSide, + viewShape: viewShape, + viewHeaderTextStyle: viewHeaderTextStyle, + viewHeaderHintStyle: viewHeaderHintStyle, + dividerColor: dividerColor, + showFullScreenView: showFullScreenView, + animation: curvedAnimation, + topPadding: topPadding, + viewMaxWidth: _rectTween.end!.width, + viewRect: viewRect, + viewBuilder: viewBuilder, + searchController: searchController, + suggestionsBuilder: suggestionsBuilder, + textCapitalization: textCapitalization, + ), ), ); } @@ -631,9 +632,6 @@ class _ViewContent extends StatefulWidget { required this.animation, required this.viewMaxWidth, required this.viewRect, - required this.viewDefaults, - required this.viewTheme, - required this.dividerTheme, required this.searchController, required this.suggestionsBuilder, }); @@ -656,9 +654,6 @@ class _ViewContent extends StatefulWidget { final Animation animation; final double viewMaxWidth; final Rect viewRect; - final SearchViewThemeData viewDefaults; - final SearchViewThemeData viewTheme; - final DividerThemeData dividerTheme; final SearchController searchController; final SuggestionsBuilder suggestionsBuilder; @@ -747,39 +742,43 @@ class _ViewContentState extends State<_ViewContent> { ), ]; + final SearchViewThemeData viewDefaults = _SearchViewDefaultsM3(context, isFullScreen: widget.showFullScreenView); + final SearchViewThemeData viewTheme = SearchViewTheme.of(context); + final DividerThemeData dividerTheme = DividerTheme.of(context); + final Color effectiveBackgroundColor = widget.viewBackgroundColor - ?? widget.viewTheme.backgroundColor - ?? widget.viewDefaults.backgroundColor!; + ?? viewTheme.backgroundColor + ?? viewDefaults.backgroundColor!; final Color effectiveSurfaceTint = widget.viewSurfaceTintColor - ?? widget.viewTheme.surfaceTintColor - ?? widget.viewDefaults.surfaceTintColor!; + ?? viewTheme.surfaceTintColor + ?? viewDefaults.surfaceTintColor!; final double effectiveElevation = widget.viewElevation - ?? widget.viewTheme.elevation - ?? widget.viewDefaults.elevation!; + ?? viewTheme.elevation + ?? viewDefaults.elevation!; final BorderSide? effectiveSide = widget.viewSide - ?? widget.viewTheme.side - ?? widget.viewDefaults.side; + ?? viewTheme.side + ?? viewDefaults.side; OutlinedBorder effectiveShape = widget.viewShape - ?? widget.viewTheme.shape - ?? widget.viewDefaults.shape!; + ?? viewTheme.shape + ?? viewDefaults.shape!; if (effectiveSide != null) { effectiveShape = effectiveShape.copyWith(side: effectiveSide); } final Color effectiveDividerColor = widget.dividerColor - ?? widget.viewTheme.dividerColor - ?? widget.dividerTheme.color - ?? widget.viewDefaults.dividerColor!; + ?? viewTheme.dividerColor + ?? dividerTheme.color + ?? viewDefaults.dividerColor!; final TextStyle? effectiveTextStyle = widget.viewHeaderTextStyle - ?? widget.viewTheme.headerTextStyle - ?? widget.viewDefaults.headerTextStyle; + ?? viewTheme.headerTextStyle + ?? viewDefaults.headerTextStyle; final TextStyle? effectiveHintStyle = widget.viewHeaderHintStyle - ?? widget.viewTheme.headerHintStyle + ?? viewTheme.headerHintStyle ?? widget.viewHeaderTextStyle - ?? widget.viewTheme.headerTextStyle - ?? widget.viewDefaults.headerHintStyle; + ?? viewTheme.headerTextStyle + ?? viewDefaults.headerHintStyle; final Widget viewDivider = DividerTheme( - data: widget.dividerTheme.copyWith(color: effectiveDividerColor), + data: dividerTheme.copyWith(color: effectiveDividerColor), child: const Divider(height: 1), ); diff --git a/packages/flutter/lib/src/material/search_view_theme.dart b/packages/flutter/lib/src/material/search_view_theme.dart index ec893000c2e83..db583be66c5d3 100644 --- a/packages/flutter/lib/src/material/search_view_theme.dart +++ b/packages/flutter/lib/src/material/search_view_theme.dart @@ -187,7 +187,7 @@ class SearchViewThemeData with Diagnosticable { /// /// * [SearchViewThemeData], which describes the actual configuration of a search view /// theme. -class SearchViewTheme extends InheritedWidget { +class SearchViewTheme extends InheritedTheme { /// Creates a const theme that controls the configurations for the search view /// created by the [SearchAnchor] widget. const SearchViewTheme({ @@ -212,6 +212,11 @@ class SearchViewTheme extends InheritedWidget { return searchViewTheme?.data ?? Theme.of(context).searchViewTheme; } + @override + Widget wrap(BuildContext context, Widget child) { + return SearchViewTheme(data: data, child: child); + } + @override bool updateShouldNotify(SearchViewTheme oldWidget) => data != oldWidget.data; } diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart index 5ee5e6116778e..235e611eddf1c 100644 --- a/packages/flutter/lib/src/material/tabs.dart +++ b/packages/flutter/lib/src/material/tabs.dart @@ -1867,6 +1867,13 @@ class _TabBarViewState extends State { _currentIndex = _controller!.index; _jumpToPage(_currentIndex!); } + if (widget.viewportFraction != oldWidget.viewportFraction) { + _pageController?.dispose(); + _pageController = PageController( + initialPage: _currentIndex!, + viewportFraction: widget.viewportFraction, + ); + } // While a warp is under way, we stop updating the tab page contents. // This is tracked in https://github.com/flutter/flutter/issues/31269. if (widget.children != oldWidget.children && _warpUnderwayCount == 0) { diff --git a/packages/flutter/lib/src/material/text_field.dart b/packages/flutter/lib/src/material/text_field.dart index e8ea4289967d8..181be1a631849 100644 --- a/packages/flutter/lib/src/material/text_field.dart +++ b/packages/flutter/lib/src/material/text_field.dart @@ -423,7 +423,12 @@ class TextField extends StatefulWidget { /// /// This text style is also used as the base style for the [decoration]. /// - /// If null, defaults to the `titleMedium` text style from the current [Theme]. + /// If null, [TextTheme.bodyLarge] will be used. When the text field is disabled, + /// [TextTheme.bodyLarge] with an opacity of 0.38 will be used instead. + /// + /// If null and [ThemeData.useMaterial3] is false, [TextTheme.titleMedium] will + /// be used. When the text field is disabled, [TextTheme.titleMedium] with + /// [ThemeData.disabledColor] will be used instead. final TextStyle? style; /// {@macro flutter.widgets.editableText.strutStyle} diff --git a/packages/flutter/lib/src/painting/placeholder_span.dart b/packages/flutter/lib/src/painting/placeholder_span.dart index 628a374102f57..1235fb92a80d2 100644 --- a/packages/flutter/lib/src/painting/placeholder_span.dart +++ b/packages/flutter/lib/src/painting/placeholder_span.dart @@ -72,20 +72,6 @@ abstract class PlaceholderSpan extends InlineSpan { collector.add(InlineSpanSemanticsInformation.placeholder); } - /// Populates the `semanticsOffsets` and `semanticsElements` with the appropriate data - /// to be able to construct a [SemanticsNode]. - /// - /// [PlaceholderSpan]s have a text length of 1, which corresponds to the object - /// replacement character (0xFFFC) that is inserted to represent it. - /// - /// Null is added to `semanticsElements` for [PlaceholderSpan]s. - void describeSemantics(Accumulator offset, List semanticsOffsets, List semanticsElements) { - semanticsOffsets.add(offset.value); - semanticsOffsets.add(offset.value + 1); - semanticsElements.add(null); // null indicates this is a placeholder. - offset.increment(1); - } - @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); diff --git a/packages/flutter/lib/src/painting/text_span.dart b/packages/flutter/lib/src/painting/text_span.dart index c3f37310332bc..634932ee6fcd3 100644 --- a/packages/flutter/lib/src/painting/text_span.dart +++ b/packages/flutter/lib/src/painting/text_span.dart @@ -431,25 +431,6 @@ class TextSpan extends InlineSpan implements HitTestTarget, MouseTrackerAnnotati return localOffset < text.length ? text.codeUnitAt(localOffset) : null; } - /// Populates the `semanticsOffsets` and `semanticsElements` with the appropriate data - /// to be able to construct a [SemanticsNode]. - /// - /// If applicable, the beginning and end text offset are added to [semanticsOffsets]. - /// [PlaceholderSpan]s have a text length of 1, which corresponds to the object - /// replacement character (0xFFFC) that is inserted to represent it. - /// - /// Any [GestureRecognizer]s are added to `semanticsElements`. Null is added to - /// `semanticsElements` for [PlaceholderSpan]s. - void describeSemantics(Accumulator offset, List semanticsOffsets, List semanticsElements) { - if (recognizer is TapGestureRecognizer || recognizer is LongPressGestureRecognizer) { - final int length = semanticsLabel?.length ?? text!.length; - semanticsOffsets.add(offset.value); - semanticsOffsets.add(offset.value + length); - semanticsElements.add(recognizer); - } - offset.increment(text != null ? text!.length : 0); - } - /// In debug mode, throws an exception if the object is not in a valid /// configuration. Otherwise, returns true. /// diff --git a/packages/flutter/lib/src/rendering/list_wheel_viewport.dart b/packages/flutter/lib/src/rendering/list_wheel_viewport.dart index bdf62c603b169..c66e97e3e55a4 100644 --- a/packages/flutter/lib/src/rendering/list_wheel_viewport.dart +++ b/packages/flutter/lib/src/rendering/list_wheel_viewport.dart @@ -1121,11 +1121,15 @@ class RenderListWheelViewport } @override - RevealedOffset getOffsetToReveal(RenderObject target, double alignment, { Rect? rect }) { + RevealedOffset getOffsetToReveal( + RenderObject target, + double alignment, { + Rect? rect, + Axis? axis, // Unused, only Axis.vertical supported by this viewport. + }) { // `target` is only fully revealed when in the selected/center position. Therefore, // this method always returns the offset that shows `target` in the center position, // which is the same offset for all `alignment` values. - rect ??= target.paintBounds; // `child` will be the last RenderObject before the viewport when walking up from `target`. diff --git a/packages/flutter/lib/src/rendering/paragraph.dart b/packages/flutter/lib/src/rendering/paragraph.dart index 13b17af303388..9ac2d9a499b51 100644 --- a/packages/flutter/lib/src/rendering/paragraph.dart +++ b/packages/flutter/lib/src/rendering/paragraph.dart @@ -132,7 +132,7 @@ mixin RenderInlineChildrenContainerDefaults on RenderBox, ContainerRenderObjectM ui.PlaceholderAlignment.belowBaseline || ui.PlaceholderAlignment.bottom || ui.PlaceholderAlignment.middle || - ui.PlaceholderAlignment.top => null, + ui.PlaceholderAlignment.top => null, ui.PlaceholderAlignment.baseline => child.getDistanceToBaseline(span.baseline!), }, ); @@ -351,8 +351,7 @@ class RenderParagraph extends RenderBox with ContainerRenderObjectMixin results = []; for (final _SelectableFragment fragment in _lastSelectableFragments!) { if (fragment._textSelectionStart != null && - fragment._textSelectionEnd != null && - fragment._textSelectionStart!.offset != fragment._textSelectionEnd!.offset) { + fragment._textSelectionEnd != null) { results.add( TextSelection( baseOffset: fragment._textSelectionStart!.offset, @@ -1309,9 +1308,9 @@ class RenderParagraph extends RenderBox with ContainerRenderObjectMixin larger.offset) { + return larger; + } else if (currentOffset < smaller.offset) { + return smaller; + } else { + return null; + } + } + @override String toString() { return '${objectRuntimeType(this, 'RevealedOffset')}(offset: $offset, rect: $rect)'; @@ -753,7 +820,16 @@ abstract class RenderViewportBase leadingEdgeOffset.offset) { - // `descendant` currently starts above the leading edge and can be shown - // fully on screen by scrolling down (which means: moving viewport up). - targetOffset = leadingEdgeOffset; - } else if (currentOffset < trailingEdgeOffset.offset) { - // `descendant currently ends below the trailing edge and can be shown - // fully on screen by scrolling up (which means: moving viewport down) - targetOffset = trailingEdgeOffset; - } else { + final RevealedOffset? targetOffset = RevealedOffset.clampOffset( + leadingEdgeOffset: leadingEdgeOffset, + trailingEdgeOffset: trailingEdgeOffset, + currentOffset: currentOffset, + ); + if (targetOffset == null) { // `descendant` is between leading and trailing edge and hence already // fully shown on screen. No action necessary. assert(viewport.parent != null); @@ -1209,7 +1253,6 @@ abstract class RenderViewportBase extends State> { @override void didUpdateWidget(FutureBuilder oldWidget) { super.didUpdateWidget(oldWidget); - if (oldWidget.future != widget.future) { - if (_activeCallbackIdentity != null) { - _unsubscribe(); - _snapshot = _snapshot.inState(ConnectionState.none); - } - _subscribe(); + if (oldWidget.future == widget.future) { + return; + } + if (_activeCallbackIdentity != null) { + _unsubscribe(); + _snapshot = _snapshot.inState(ConnectionState.none); } + _subscribe(); } @override @@ -614,33 +615,35 @@ class _FutureBuilderState extends State> { } void _subscribe() { - if (widget.future != null) { - final Object callbackIdentity = Object(); - _activeCallbackIdentity = callbackIdentity; - widget.future!.then((T data) { - if (_activeCallbackIdentity == callbackIdentity) { - setState(() { - _snapshot = AsyncSnapshot.withData(ConnectionState.done, data); - }); - } - }, onError: (Object error, StackTrace stackTrace) { - if (_activeCallbackIdentity == callbackIdentity) { - setState(() { - _snapshot = AsyncSnapshot.withError(ConnectionState.done, error, stackTrace); - }); - } - assert(() { - if (FutureBuilder.debugRethrowError) { - Future.error(error, stackTrace); - } - return true; - }()); - }); - // An implementation like `SynchronousFuture` may have already called the - // .then closure. Do not overwrite it in that case. - if (_snapshot.connectionState != ConnectionState.done) { - _snapshot = _snapshot.inState(ConnectionState.waiting); + if (widget.future == null) { + // There is no future to subscribe to, do nothing. + return; + } + final Object callbackIdentity = Object(); + _activeCallbackIdentity = callbackIdentity; + widget.future!.then((T data) { + if (_activeCallbackIdentity == callbackIdentity) { + setState(() { + _snapshot = AsyncSnapshot.withData(ConnectionState.done, data); + }); } + }, onError: (Object error, StackTrace stackTrace) { + if (_activeCallbackIdentity == callbackIdentity) { + setState(() { + _snapshot = AsyncSnapshot.withError(ConnectionState.done, error, stackTrace); + }); + } + assert(() { + if (FutureBuilder.debugRethrowError) { + Future.error(error, stackTrace); + } + return true; + }()); + }); + // An implementation like `SynchronousFuture` may have already called the + // .then closure. Do not overwrite it in that case. + if (_snapshot.connectionState != ConnectionState.done) { + _snapshot = _snapshot.inState(ConnectionState.waiting); } } diff --git a/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart b/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart index e8e56fc47ab34..eaf615a5eff8a 100644 --- a/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart +++ b/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart @@ -52,6 +52,13 @@ typedef ScrollableWidgetBuilder = Widget Function( /// fire when [pixels] changes without [size] changing. For example, if the /// constraints provided to an attached sheet change. class DraggableScrollableController extends ChangeNotifier { + /// Creates a controller for [DraggableScrollableSheet]. + DraggableScrollableController() { + if (kFlutterMemoryAllocationsEnabled) { + ChangeNotifier.maybeDispatchObjectCreation(this); + } + } + _DraggableScrollableSheetScrollController? _attachedController; final Set _animationControllers = {}; diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart index 339c6405fa47a..c4c376565aae1 100644 --- a/packages/flutter/lib/src/widgets/editable_text.dart +++ b/packages/flutter/lib/src/widgets/editable_text.dart @@ -3488,11 +3488,7 @@ class EditableTextState extends State with AutomaticKeepAliveClien _textInputConnection!.connectionClosedReceived(); _textInputConnection = null; _lastKnownRemoteTextEditingValue = null; - if (kIsWeb) { - _finalizeEditing(TextInputAction.done, shouldUnfocus: true); - } else { - widget.focusNode.unfocus(); - } + widget.focusNode.unfocus(); } } diff --git a/packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart b/packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart index 6a20487ebe216..ba52e9b2bd4c0 100644 --- a/packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart +++ b/packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart @@ -217,6 +217,8 @@ class FixedExtentScrollController extends ScrollController { /// [initialItem] defaults to zero. FixedExtentScrollController({ this.initialItem = 0, + super.onAttach, + super.onDetach, }); /// The page to show when first creating the scroll view. diff --git a/packages/flutter/lib/src/widgets/page_view.dart b/packages/flutter/lib/src/widgets/page_view.dart index ddd0603edc474..6e973dbbe44ee 100644 --- a/packages/flutter/lib/src/widgets/page_view.dart +++ b/packages/flutter/lib/src/widgets/page_view.dart @@ -116,6 +116,8 @@ class PageController extends ScrollController { this.initialPage = 0, this.keepPage = true, this.viewportFraction = 1.0, + super.onAttach, + super.onDetach, }) : assert(viewportFraction > 0.0); /// The page to show when first creating the [PageView]. diff --git a/packages/flutter/lib/src/widgets/scroll_controller.dart b/packages/flutter/lib/src/widgets/scroll_controller.dart index de88a41acc4a5..d9a478328ce92 100644 --- a/packages/flutter/lib/src/widgets/scroll_controller.dart +++ b/packages/flutter/lib/src/widgets/scroll_controller.dart @@ -380,6 +380,8 @@ class TrackingScrollController extends ScrollController { super.initialScrollOffset, super.keepScrollOffset, super.debugLabel, + super.onAttach, + super.onDetach, }); final Map _positionToListener = {}; diff --git a/packages/flutter/lib/src/widgets/scroll_position.dart b/packages/flutter/lib/src/widgets/scroll_position.dart index 6311b1aae493c..e1ec77eae2b78 100644 --- a/packages/flutter/lib/src/widgets/scroll_position.dart +++ b/packages/flutter/lib/src/widgets/scroll_position.dart @@ -810,14 +810,32 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { double target; switch (_applyAxisDirectionToAlignmentPolicy(alignmentPolicy)) { case ScrollPositionAlignmentPolicy.explicit: - target = clampDouble(viewport.getOffsetToReveal(object, alignment, rect: targetRect).offset, minScrollExtent, maxScrollExtent); + target = viewport.getOffsetToReveal( + object, + alignment, + rect: targetRect, + axis: axis, + ).offset; + target = clampDouble(target, minScrollExtent, maxScrollExtent); case ScrollPositionAlignmentPolicy.keepVisibleAtEnd: - target = clampDouble(viewport.getOffsetToReveal(object, 1.0, rect: targetRect).offset, minScrollExtent, maxScrollExtent); + target = viewport.getOffsetToReveal( + object, + 1.0, // Aligns to end + rect: targetRect, + axis: axis, + ).offset; + target = clampDouble(target, minScrollExtent, maxScrollExtent); if (target < pixels) { target = pixels; } case ScrollPositionAlignmentPolicy.keepVisibleAtStart: - target = clampDouble(viewport.getOffsetToReveal(object, 0.0, rect: targetRect).offset, minScrollExtent, maxScrollExtent); + target = viewport.getOffsetToReveal( + object, + 0.0, // Aligns to start + rect: targetRect, + axis: axis, + ).offset; + target = clampDouble(target, minScrollExtent, maxScrollExtent); if (target > pixels) { target = pixels; } diff --git a/packages/flutter/lib/src/widgets/scrollable.dart b/packages/flutter/lib/src/widgets/scrollable.dart index 88bd115771451..86c350401d4b6 100644 --- a/packages/flutter/lib/src/widgets/scrollable.dart +++ b/packages/flutter/lib/src/widgets/scrollable.dart @@ -44,6 +44,13 @@ typedef ViewportBuilder = Widget Function(BuildContext context, ViewportOffset p /// which the scrollable content is displayed. typedef TwoDimensionalViewportBuilder = Widget Function(BuildContext context, ViewportOffset verticalPosition, ViewportOffset horizontalPosition); +// The return type of _performEnsureVisible. +// +// The list of futures represents each pending ScrollPosition call to +// ensureVisible. The returned ScrollableState's context is used to find the +// next potential ancestor Scrollable. +typedef _EnsureVisibleResults = (List>, ScrollableState); + /// A widget that manages scrolling in one dimension and informs the [Viewport] /// through which the content is viewed. /// @@ -441,6 +448,10 @@ class Scrollable extends StatefulWidget { /// Scrolls the scrollables that enclose the given context so as to make the /// given context visible. + /// + /// If the [Scrollable] of the provided [BuildContext] is a + /// [TwoDimensionalScrollable], both vertical and horizontal axes will ensure + /// the target is made visible. static Future ensureVisible( BuildContext context, { double alignment = 0.0, @@ -459,14 +470,16 @@ class Scrollable extends StatefulWidget { RenderObject? targetRenderObject; ScrollableState? scrollable = Scrollable.maybeOf(context); while (scrollable != null) { - futures.add(scrollable.position.ensureVisible( + final List> newFutures; + (newFutures, scrollable) = scrollable._performEnsureVisible( context.findRenderObject()!, alignment: alignment, duration: duration, curve: curve, alignmentPolicy: alignmentPolicy, targetRenderObject: targetRenderObject, - )); + ); + futures.addAll(newFutures); targetRenderObject = targetRenderObject ?? context.findRenderObject(); context = scrollable.context; @@ -657,7 +670,7 @@ class ScrollableState extends State with TickerProviderStateMixin, R if (oldWidget.controller == null) { // The old controller was null, meaning the fallback cannot be null. // Dispose of the fallback. - assert(_fallbackScrollController != null); + assert(_fallbackScrollController != null); assert(widget.controller != null); _fallbackScrollController!.detach(position); _fallbackScrollController!.dispose(); @@ -1011,6 +1024,28 @@ class ScrollableState extends State with TickerProviderStateMixin, R return result; } + // Returns the Future from calling ensureVisible for the ScrollPosition, as + // as well as this ScrollableState instance so its context can be used to + // check for other ancestor Scrollables in executing ensureVisible. + _EnsureVisibleResults _performEnsureVisible( + RenderObject object, { + double alignment = 0.0, + Duration duration = Duration.zero, + Curve curve = Curves.ease, + ScrollPositionAlignmentPolicy alignmentPolicy = ScrollPositionAlignmentPolicy.explicit, + RenderObject? targetRenderObject, + }) { + final Future ensureVisibleFuture = position.ensureVisible( + object, + alignment: alignment, + duration: duration, + curve: curve, + alignmentPolicy: alignmentPolicy, + targetRenderObject: targetRenderObject, + ); + return (>[ ensureVisibleFuture ], this); + } + @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); @@ -1919,7 +1954,7 @@ class TwoDimensionalScrollableState extends State { if (oldWidget.horizontalDetails.controller == null) { // The old controller was null, meaning the fallback cannot be null. // Dispose of the fallback. - assert(_horizontalFallbackController != null); + assert(_horizontalFallbackController != null); assert(widget.horizontalDetails.controller != null); _horizontalFallbackController!.dispose(); _horizontalFallbackController = null; @@ -2040,6 +2075,25 @@ class _VerticalOuterDimension extends Scrollable { class _VerticalOuterDimensionState extends ScrollableState { DiagonalDragBehavior get diagonalDragBehavior => (widget as _VerticalOuterDimension).diagonalDragBehavior; + // Implemented in the _HorizontalInnerDimension instead. + @override + _EnsureVisibleResults _performEnsureVisible( + RenderObject object, { + double alignment = 0.0, + Duration duration = Duration.zero, + Curve curve = Curves.ease, + ScrollPositionAlignmentPolicy alignmentPolicy = ScrollPositionAlignmentPolicy.explicit, + RenderObject? targetRenderObject, + }) { + assert( + false, + 'The _performEnsureVisible method was called for the vertical scrollable ' + 'of a TwoDimensionalScrollable. This should not happen as the horizontal ' + 'scrollable handles both axes.' + ); + return (>[], this); + } + @override void setCanDrag(bool value) { switch (diagonalDragBehavior) { @@ -2119,6 +2173,39 @@ class _HorizontalInnerDimensionState extends ScrollableState { super.didChangeDependencies(); } + // Returns the Future from calling ensureVisible for the ScrollPosition, as + // as well as the vertical ScrollableState instance so its context can be + // used to check for other ancestor Scrollables in executing ensureVisible. + @override + _EnsureVisibleResults _performEnsureVisible( + RenderObject object, { + double alignment = 0.0, + Duration duration = Duration.zero, + Curve curve = Curves.ease, + ScrollPositionAlignmentPolicy alignmentPolicy = ScrollPositionAlignmentPolicy.explicit, + RenderObject? targetRenderObject, + }) { + final List> newFutures = >[]; + + newFutures.add(position.ensureVisible( + object, + alignment: alignment, + duration: duration, + curve: curve, + alignmentPolicy: alignmentPolicy, + )); + + newFutures.add(verticalScrollable.position.ensureVisible( + object, + alignment: alignment, + duration: duration, + curve: curve, + alignmentPolicy: alignmentPolicy, + )); + + return (newFutures, verticalScrollable); + } + void _evaluateLockedAxis(Offset offset) { assert(lastDragOffset != null); final Offset offsetDelta = lastDragOffset! - offset; diff --git a/packages/flutter/lib/src/widgets/selectable_region.dart b/packages/flutter/lib/src/widgets/selectable_region.dart index 4b972c081e311..70369b8b3a08e 100644 --- a/packages/flutter/lib/src/widgets/selectable_region.dart +++ b/packages/flutter/lib/src/widgets/selectable_region.dart @@ -352,7 +352,8 @@ class SelectableRegionState extends State with TextSelectionDe _showToolbar(location: details.globalPosition); } } else { - _clearSelection(); + hideToolbar(); + _collapseSelectionAt(offset: details.globalPosition); } }; instance.onSecondaryTapDown = _handleRightClickDown; @@ -472,6 +473,7 @@ class SelectableRegionState extends State with TextSelectionDe (TapAndPanGestureRecognizer instance) { instance ..onTapDown = _startNewMouseSelectionGesture + ..onTapUp = _handleMouseTapUp ..onDragStart = _handleMouseDragStart ..onDragUpdate = _handleMouseDragUpdate ..onDragEnd = _handleMouseDragEnd @@ -498,7 +500,17 @@ class SelectableRegionState extends State with TextSelectionDe case 1: widget.focusNode.requestFocus(); hideToolbar(); - _clearSelection(); + switch (defaultTargetPlatform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.iOS: + // On mobile platforms the selection is set on tap up. + break; + case TargetPlatform.macOS: + case TargetPlatform.linux: + case TargetPlatform.windows: + _collapseSelectionAt(offset: details.globalPosition); + } case 2: _selectWordAt(offset: details.globalPosition); } @@ -528,6 +540,24 @@ class SelectableRegionState extends State with TextSelectionDe _updateSelectedContentIfNeeded(); } + void _handleMouseTapUp(TapDragUpDetails details) { + switch (_getEffectiveConsecutiveTapCount(details.consecutiveTapCount)) { + case 1: + switch (defaultTargetPlatform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.iOS: + _collapseSelectionAt(offset: details.globalPosition); + case TargetPlatform.macOS: + case TargetPlatform.linux: + case TargetPlatform.windows: + // On desktop platforms the selection is set on tap down. + break; + } + } + _updateSelectedContentIfNeeded(); + } + void _updateSelectedContentIfNeeded() { if (_lastSelectedContent?.plainText != _selectable?.getSelectedContent()?.plainText) { _lastSelectedContent = _selectable?.getSelectedContent(); @@ -586,8 +616,7 @@ class SelectableRegionState extends State with TextSelectionDe // keep the current selection, if not then collapse it. final bool lastSecondaryTapDownPositionWasOnActiveSelection = _positionIsOnActiveSelection(globalPosition: details.globalPosition); if (!lastSecondaryTapDownPositionWasOnActiveSelection) { - _selectStartTo(offset: lastSecondaryTapDownPosition!); - _selectEndTo(offset: lastSecondaryTapDownPosition!); + _collapseSelectionAt(offset: lastSecondaryTapDownPosition!); } _showHandles(); _showToolbar(location: lastSecondaryTapDownPosition); @@ -612,8 +641,7 @@ class SelectableRegionState extends State with TextSelectionDe // keep the current selection, if not then collapse it. final bool lastSecondaryTapDownPositionWasOnActiveSelection = _positionIsOnActiveSelection(globalPosition: details.globalPosition); if (!lastSecondaryTapDownPositionWasOnActiveSelection) { - _selectStartTo(offset: lastSecondaryTapDownPosition!); - _selectEndTo(offset: lastSecondaryTapDownPosition!); + _collapseSelectionAt(offset: lastSecondaryTapDownPosition!); } _showHandles(); _showToolbar(location: lastSecondaryTapDownPosition); @@ -925,8 +953,9 @@ class SelectableRegionState extends State with TextSelectionDe /// See also: /// * [_selectStartTo], which sets or updates selection start edge. /// * [_finalizeSelection], which stops the `continuous` updates. - /// * [_clearSelection], which clear the ongoing selection. + /// * [_clearSelection], which clears the ongoing selection. /// * [_selectWordAt], which selects a whole word at the location. + /// * [_collapseSelectionAt], which collapses the selection at the location. /// * [selectAll], which selects the entire content. void _selectEndTo({required Offset offset, bool continuous = false, TextGranularity? textGranularity}) { if (!continuous) { @@ -964,8 +993,9 @@ class SelectableRegionState extends State with TextSelectionDe /// See also: /// * [_selectEndTo], which sets or updates selection end edge. /// * [_finalizeSelection], which stops the `continuous` updates. - /// * [_clearSelection], which clear the ongoing selection. + /// * [_clearSelection], which clears the ongoing selection. /// * [_selectWordAt], which selects a whole word at the location. + /// * [_collapseSelectionAt], which collapses the selection at the location. /// * [selectAll], which selects the entire content. void _selectStartTo({required Offset offset, bool continuous = false, TextGranularity? textGranularity}) { if (!continuous) { @@ -978,6 +1008,20 @@ class SelectableRegionState extends State with TextSelectionDe } } + /// Collapses the selection at the given `offset` location. + /// + /// See also: + /// * [_selectStartTo], which sets or updates selection start edge. + /// * [_selectEndTo], which sets or updates selection end edge. + /// * [_finalizeSelection], which stops the `continuous` updates. + /// * [_clearSelection], which clears the ongoing selection. + /// * [_selectWordAt], which selects a whole word at the location. + /// * [selectAll], which selects the entire content. + void _collapseSelectionAt({required Offset offset}) { + _selectStartTo(offset: offset); + _selectEndTo(offset: offset); + } + /// Selects a whole word at the `offset` location. /// /// If the whole word is already in the current selection, selection won't @@ -991,7 +1035,8 @@ class SelectableRegionState extends State with TextSelectionDe /// * [_selectStartTo], which sets or updates selection start edge. /// * [_selectEndTo], which sets or updates selection end edge. /// * [_finalizeSelection], which stops the `continuous` updates. - /// * [_clearSelection], which clear the ongoing selection. + /// * [_clearSelection], which clears the ongoing selection. + /// * [_collapseSelectionAt], which collapses the selection at the location. /// * [selectAll], which selects the entire content. void _selectWordAt({required Offset offset}) { // There may be other selection ongoing. @@ -1881,7 +1926,7 @@ abstract class MultiSelectableSelectionContainerDelegate extends SelectionContai SelectionPoint? startPoint; if (startGeometry.startSelectionPoint != null) { - final Matrix4 startTransform = getTransformFrom(selectables[startIndexWalker]); + final Matrix4 startTransform = getTransformFrom(selectables[startIndexWalker]); final Offset start = MatrixUtils.transformPoint(startTransform, startGeometry.startSelectionPoint!.localPosition); // It can be NaN if it is detached or off-screen. if (start.isFinite) { @@ -1902,7 +1947,7 @@ abstract class MultiSelectableSelectionContainerDelegate extends SelectionContai } SelectionPoint? endPoint; if (endGeometry.endSelectionPoint != null) { - final Matrix4 endTransform = getTransformFrom(selectables[endIndexWalker]); + final Matrix4 endTransform = getTransformFrom(selectables[endIndexWalker]); final Offset end = MatrixUtils.transformPoint(endTransform, endGeometry.endSelectionPoint!.localPosition); // It can be NaN if it is detached or off-screen. if (end.isFinite) { @@ -1986,8 +2031,8 @@ abstract class MultiSelectableSelectionContainerDelegate extends SelectionContai final Rect? drawableArea = hasSize ? Rect .fromLTWH(0, 0, containerSize.width, containerSize.height) .inflate(_kSelectionHandleDrawableAreaPadding) : null; - final bool hideStartHandle = value.startSelectionPoint == null || drawableArea == null || !drawableArea.contains(value.startSelectionPoint!.localPosition); - final bool hideEndHandle = value.endSelectionPoint == null || drawableArea == null|| !drawableArea.contains(value.endSelectionPoint!.localPosition); + final bool hideStartHandle = value.startSelectionPoint == null || drawableArea == null || !drawableArea.contains(value.startSelectionPoint!.localPosition); + final bool hideEndHandle = value.endSelectionPoint == null || drawableArea == null|| !drawableArea.contains(value.endSelectionPoint!.localPosition); effectiveStartHandle = hideStartHandle ? null : _startHandleLayer; effectiveEndHandle = hideEndHandle ? null : _endHandleLayer; } @@ -2047,6 +2092,34 @@ abstract class MultiSelectableSelectionContainerDelegate extends SelectionContai ); } + // Clears the selection on all selectables not in the range of + // currentSelectionStartIndex..currentSelectionEndIndex. + // + // If one of the edges does not exist, then this method will clear the selection + // in all selectables except the existing edge. + // + // If neither of the edges exist this method immediately returns. + void _flushInactiveSelections() { + if (currentSelectionStartIndex == -1 && currentSelectionEndIndex == -1) { + return; + } + if (currentSelectionStartIndex == -1 || currentSelectionEndIndex == -1) { + final int skipIndex = currentSelectionStartIndex == -1 ? currentSelectionEndIndex : currentSelectionStartIndex; + selectables + .where((Selectable target) => target != selectables[skipIndex]) + .forEach((Selectable target) => dispatchSelectionEventToChild(target, const ClearSelectionEvent())); + return; + } + final int skipStart = min(currentSelectionStartIndex, currentSelectionEndIndex); + final int skipEnd = max(currentSelectionStartIndex, currentSelectionEndIndex); + for (int index = 0; index < selectables.length; index += 1) { + if (index >= skipStart && index <= skipEnd) { + continue; + } + dispatchSelectionEventToChild(selectables[index], const ClearSelectionEvent()); + } + } + /// Selects all contents of all selectables. @protected SelectionResult handleSelectAll(SelectAllSelectionEvent event) { @@ -2290,7 +2363,7 @@ abstract class MultiSelectableSelectionContainerDelegate extends SelectionContai bool hasFoundEdgeIndex = false; SelectionResult? result; for (int index = 0; index < selectables.length && !hasFoundEdgeIndex; index += 1) { - final Selectable child = selectables[index]; + final Selectable child = selectables[index]; final SelectionResult childResult = dispatchSelectionEventToChild(child, event); switch (childResult) { case SelectionResult.next: @@ -2323,6 +2396,7 @@ abstract class MultiSelectableSelectionContainerDelegate extends SelectionContai } else { currentSelectionStartIndex = newIndex; } + _flushInactiveSelections(); // The result can only be null if the loop went through the entire list // without any of the selection returned end or previous. In this case, the // caller of this method needs to find the next selectable in their list. @@ -2345,13 +2419,39 @@ abstract class MultiSelectableSelectionContainerDelegate extends SelectionContai return true; }()); SelectionResult? finalResult; - int newIndex = isEnd ? currentSelectionEndIndex : currentSelectionStartIndex; + // Determines if the edge being adjusted is within the current viewport. + // - If so, we begin the search for the new selection edge position at the + // currentSelectionEndIndex/currentSelectionStartIndex. + // - If not, we attempt to locate the new selection edge starting from + // the opposite end. + // - If neither edge is in the current viewport, the search for the new + // selection edge position begins at 0. + // + // This can happen when there is a scrollable child and the edge being adjusted + // has been scrolled out of view. + final bool isCurrentEdgeWithinViewport = isEnd ? _selectionGeometry.endSelectionPoint != null : _selectionGeometry.startSelectionPoint != null; + final bool isOppositeEdgeWithinViewport = isEnd ? _selectionGeometry.startSelectionPoint != null : _selectionGeometry.endSelectionPoint != null; + int newIndex = switch ((isEnd, isCurrentEdgeWithinViewport, isOppositeEdgeWithinViewport)) { + (true, true, true) => currentSelectionEndIndex, + (true, true, false) => currentSelectionEndIndex, + (true, false, true) => currentSelectionStartIndex, + (true, false, false) => 0, + (false, true, true) => currentSelectionStartIndex, + (false, true, false) => currentSelectionStartIndex, + (false, false, true) => currentSelectionEndIndex, + (false, false, false) => 0, + }; bool? forward; late SelectionResult currentSelectableResult; - // This loop sends the selection event to the - // currentSelectionEndIndex/currentSelectionStartIndex to determine the - // direction of the search. If the result is `SelectionResult.next`, this - // loop look backward. Otherwise, it looks forward. + // This loop sends the selection event to one of the following to determine + // the direction of the search. + // - currentSelectionEndIndex/currentSelectionStartIndex if the current edge + // is in the current viewport. + // - The opposite edge index if the current edge is not in the current viewport. + // - Index 0 if neither edge is in the current viewport. + // + // If the result is `SelectionResult.next`, this loop look backward. + // Otherwise, it looks forward. // // The terminate condition are: // 1. the selectable returns end, pending, none. @@ -2391,6 +2491,7 @@ abstract class MultiSelectableSelectionContainerDelegate extends SelectionContai } else { currentSelectionStartIndex = newIndex; } + _flushInactiveSelections(); return finalResult!; } } diff --git a/packages/flutter/lib/src/widgets/single_child_scroll_view.dart b/packages/flutter/lib/src/widgets/single_child_scroll_view.dart index 53cb54846eb76..59b4956f5f7dc 100644 --- a/packages/flutter/lib/src/widgets/single_child_scroll_view.dart +++ b/packages/flutter/lib/src/widgets/single_child_scroll_view.dart @@ -592,7 +592,16 @@ class _RenderSingleChildViewport extends RenderBox with RenderObjectWithChildMix } @override - RevealedOffset getOffsetToReveal(RenderObject target, double alignment, { Rect? rect }) { + RevealedOffset getOffsetToReveal( + RenderObject target, + double alignment, { + Rect? rect, + Axis? axis, + }) { + // One dimensional viewport has only one axis, override if it was + // provided/may be mismatched. + axis = this.axis; + rect ??= target.paintBounds; if (target is! RenderBox) { return RevealedOffset(offset: offset.pixels, rect: rect); diff --git a/packages/flutter/lib/src/widgets/two_dimensional_viewport.dart b/packages/flutter/lib/src/widgets/two_dimensional_viewport.dart index 282ef44490874..5759df9c90e9a 100644 --- a/packages/flutter/lib/src/widgets/two_dimensional_viewport.dart +++ b/packages/flutter/lib/src/widgets/two_dimensional_viewport.dart @@ -4,6 +4,7 @@ import 'dart:math' as math; +import 'package:flutter/animation.dart'; import 'package:flutter/rendering.dart'; import 'framework.dart'; @@ -497,7 +498,6 @@ class TwoDimensionalViewportParentData extends ParentData with KeepAliveParentD /// /// Subclasses should not override [performLayout], as it handles housekeeping /// on either side of the call to [layoutChildSequence]. -// TODO(Piinks): ensureVisible https://github.com/flutter/flutter/issues/126299 abstract class RenderTwoDimensionalViewport extends RenderBox implements RenderAbstractViewport { /// Initializes fields for subclasses. /// @@ -848,11 +848,7 @@ abstract class RenderTwoDimensionalViewport extends RenderBox implements RenderA RenderBox? child = _firstChild; while (child != null) { final TwoDimensionalViewportParentData childParentData = parentDataOf(child); - // TODO(Piinks): When ensure visible is supported, remove this isVisible - // condition. - if (childParentData.isVisible) { - visitor(child); - } + visitor(child); child = childParentData._nextSibling; } // Do not visit children in [_keepAliveBucket]. @@ -920,10 +916,273 @@ abstract class RenderTwoDimensionalViewport extends RenderBox implements RenderA } } + @protected + @override + RevealedOffset getOffsetToReveal( + RenderObject target, + double alignment, { + Rect? rect, + Axis? axis, + }) { + // If an axis has not been specified, use the mainAxis. + axis ??= mainAxis; + + final (double offset, AxisDirection axisDirection) = switch (axis) { + Axis.vertical => (verticalOffset.pixels, verticalAxisDirection), + Axis.horizontal => (horizontalOffset.pixels, horizontalAxisDirection), + }; + + rect ??= target.paintBounds; + // `child` will be the last RenderObject before the viewport when walking + // up from `target`. + RenderObject child = target; + while (child.parent != this) { + child = child.parent!; + } + + assert(child.parent == this); + final RenderBox box = child as RenderBox; + final Rect rectLocal = MatrixUtils.transformRect(target.getTransformTo(child), rect); + + final double targetMainAxisExtent; + double leadingScrollOffset = offset; + // The scroll offset of `rect` within `child`. + switch (axisDirection) { + case AxisDirection.up: + leadingScrollOffset += child.size.height - rectLocal.bottom; + targetMainAxisExtent = rectLocal.height; + case AxisDirection.right: + leadingScrollOffset += rectLocal.left; + targetMainAxisExtent = rectLocal.width; + case AxisDirection.down: + leadingScrollOffset += rectLocal.top; + targetMainAxisExtent = rectLocal.height; + case AxisDirection.left: + leadingScrollOffset += child.size.width - rectLocal.right; + targetMainAxisExtent = rectLocal.width; + } + + // The scroll offset in the viewport to `rect`. + final TwoDimensionalViewportParentData childParentData = parentDataOf(box); + leadingScrollOffset += switch (axisDirection) { + AxisDirection.down => childParentData.paintOffset!.dy, + AxisDirection.up => viewportDimension.height - childParentData.paintOffset!.dy - box.size.height, + AxisDirection.right => childParentData.paintOffset!.dx, + AxisDirection.left => viewportDimension.width - childParentData.paintOffset!.dx - box.size.width, + }; + + // This step assumes the viewport's layout is up-to-date, i.e., if + // the position is changed after the last performLayout, the new scroll + // position will not be accounted for. + final Matrix4 transform = target.getTransformTo(this); + Rect targetRect = MatrixUtils.transformRect(transform, rect); + + final double mainAxisExtent = switch (axisDirectionToAxis(axisDirection)) { + Axis.horizontal => viewportDimension.width, + Axis.vertical => viewportDimension.height, + }; + + final double targetOffset = leadingScrollOffset - (mainAxisExtent - targetMainAxisExtent) * alignment; + + final double offsetDifference = switch (axisDirectionToAxis(axisDirection)){ + Axis.vertical => verticalOffset.pixels - targetOffset, + Axis.horizontal => horizontalOffset.pixels - targetOffset, + }; + switch (axisDirection) { + case AxisDirection.down: + targetRect = targetRect.translate(0.0, offsetDifference); + case AxisDirection.right: + targetRect = targetRect.translate(offsetDifference, 0.0); + case AxisDirection.up: + targetRect = targetRect.translate(0.0, -offsetDifference); + case AxisDirection.left: + targetRect = targetRect.translate(-offsetDifference, 0.0); + } + + final RevealedOffset revealedOffset = RevealedOffset( + offset: targetOffset, + rect: targetRect, + ); + return revealedOffset; + } + @override - RevealedOffset getOffsetToReveal(RenderObject target, double alignment, { Rect? rect }) { - // TODO(Piinks): Add this back in follow up change (ensureVisible), https://github.com/flutter/flutter/issues/126299 - return const RevealedOffset(offset: 0.0, rect: Rect.zero); + void showOnScreen({ + RenderObject? descendant, + Rect? rect, + Duration duration = Duration.zero, + Curve curve = Curves.ease, + }) { + // It is possible for one and not both axes to allow for implicit scrolling, + // so handling is split between the options for allowed implicit scrolling. + final bool allowHorizontal = horizontalOffset.allowImplicitScrolling; + final bool allowVertical = verticalOffset.allowImplicitScrolling; + AxisDirection? axisDirection; + switch ((allowHorizontal, allowVertical)) { + case (true, true): + // Both allow implicit scrolling. + break; + case (false, true): + // Only the vertical Axis allows implicit scrolling. + axisDirection = verticalAxisDirection; + case (true, false): + // Only the horizontal Axis allows implicit scrolling. + axisDirection = horizontalAxisDirection; + case (false, false): + // Neither axis allows for implicit scrolling. + return super.showOnScreen( + descendant: descendant, + rect: rect, + duration: duration, + curve: curve, + ); + } + + final Rect? newRect = RenderTwoDimensionalViewport.showInViewport( + descendant: descendant, + viewport: this, + axisDirection: axisDirection, + rect: rect, + duration: duration, + curve: curve, + ); + + super.showOnScreen( + rect: newRect, + duration: duration, + curve: curve, + ); + } + + /// Make (a portion of) the given `descendant` of the given `viewport` fully + /// visible in one or both dimensions of the `viewport` by manipulating the + /// [ViewportOffset]s. + /// + /// The `axisDirection` determines from which axes the `descendant` will be + /// revealed. When the `axisDirection` is null, both axes will be updated to + /// reveal the descendant. + /// + /// The optional `rect` parameter describes which area of the `descendant` + /// should be shown in the viewport. If `rect` is null, the entire + /// `descendant` will be revealed. The `rect` parameter is interpreted + /// relative to the coordinate system of `descendant`. + /// + /// The returned [Rect] describes the new location of `descendant` or `rect` + /// in the viewport after it has been revealed. See [RevealedOffset.rect] + /// for a full definition of this [Rect]. + /// + /// The parameter `viewport` is required and cannot be null. If `descendant` + /// is null, this is a no-op and `rect` is returned. + /// + /// If both `descendant` and `rect` are null, null is returned because there + /// is nothing to be shown in the viewport. + /// + /// The `duration` parameter can be set to a non-zero value to animate the + /// target object into the viewport with an animation defined by `curve`. + /// + /// See also: + /// + /// * [RenderObject.showOnScreen], overridden by + /// [RenderTwoDimensionalViewport] to delegate to this method. + static Rect? showInViewport({ + RenderObject? descendant, + Rect? rect, + required RenderTwoDimensionalViewport viewport, + Duration duration = Duration.zero, + Curve curve = Curves.ease, + AxisDirection? axisDirection, + }) { + if (descendant == null) { + return rect; + } + + Rect? showVertical(Rect? rect) { + return RenderTwoDimensionalViewport._showInViewportForAxisDirection( + descendant: descendant, + viewport: viewport, + axis: Axis.vertical, + rect: rect, + duration: duration, + curve: curve, + ); + } + + Rect? showHorizontal(Rect? rect) { + return RenderTwoDimensionalViewport._showInViewportForAxisDirection( + descendant: descendant, + viewport: viewport, + axis: Axis.horizontal, + rect: rect, + duration: duration, + curve: curve, + ); + } + + switch (axisDirection) { + case AxisDirection.left: + case AxisDirection.right: + return showHorizontal(rect); + case AxisDirection.up: + case AxisDirection.down: + return showVertical(rect); + case null: + // Update rect after revealing in one axis before revealing in the next. + rect = showHorizontal(rect) ?? rect; + // We only return the final rect after both have been revealed. + rect = showVertical(rect); + if (rect == null) { + // `descendant` is between leading and trailing edge and hence already + // fully shown on screen. + assert(viewport.parent != null); + final Matrix4 transform = descendant.getTransformTo(viewport.parent); + return MatrixUtils.transformRect( + transform, + rect ?? descendant.paintBounds, + ); + } + return rect; + } + } + + static Rect? _showInViewportForAxisDirection({ + required RenderObject descendant, + Rect? rect, + required RenderTwoDimensionalViewport viewport, + required Axis axis, + Duration duration = Duration.zero, + Curve curve = Curves.ease, + }) { + final ViewportOffset offset = switch (axis) { + Axis.vertical => viewport.verticalOffset, + Axis.horizontal => viewport.horizontalOffset, + }; + + final RevealedOffset leadingEdgeOffset = viewport.getOffsetToReveal( + descendant, + 0.0, + rect: rect, + axis: axis, + ); + final RevealedOffset trailingEdgeOffset = viewport.getOffsetToReveal( + descendant, + 1.0, + rect: rect, + axis: axis, + ); + final double currentOffset = offset.pixels; + + final RevealedOffset? targetOffset = RevealedOffset.clampOffset( + leadingEdgeOffset: leadingEdgeOffset, + trailingEdgeOffset: trailingEdgeOffset, + currentOffset: currentOffset, + ); + if (targetOffset == null) { + // Already visible in this axis. + return null; + } + + offset.moveTo(targetOffset.offset, duration: duration, curve: curve); + return targetOffset.rect; } /// Should be used by subclasses to invalidate any cached metrics for the diff --git a/packages/flutter/lib/src/widgets/widget_inspector.dart b/packages/flutter/lib/src/widgets/widget_inspector.dart index bf6324d2ec9b7..7bc4873965712 100644 --- a/packages/flutter/lib/src/widgets/widget_inspector.dart +++ b/packages/flutter/lib/src/widgets/widget_inspector.dart @@ -372,6 +372,12 @@ class _ScreenshotData { set screenshotOffset(Offset offset) { containerLayer.offset = offset; } + + /// Releases allocated resources. + @mustCallSuper + void dispose() { + containerLayer.dispose(); + } } /// A place to paint to build screenshots of [RenderObject]s. @@ -550,7 +556,7 @@ class _ScreenshotPaintingContext extends PaintingContext { Rect renderBounds, { double pixelRatio = 1.0, bool debugPaint = false, - }) { + }) async { RenderObject repaintBoundary = renderObject; while (!repaintBoundary.isRepaintBoundary) { repaintBoundary = repaintBoundary.parent!; @@ -604,7 +610,15 @@ class _ScreenshotPaintingContext extends PaintingContext { // been called successfully for all layers in the regular scene. repaintBoundary.debugLayer!.buildScene(ui.SceneBuilder()); - return data.containerLayer.toImage(renderBounds, pixelRatio: pixelRatio); + final ui.Image image; + + try { + image = await data.containerLayer.toImage(renderBounds, pixelRatio: pixelRatio); + } finally { + data.dispose(); + } + + return image; } } @@ -1285,6 +1299,7 @@ mixin WidgetInspectorService { return {'result': null}; } final ByteData? byteData = await image.toByteData(format:ui.ImageByteFormat.png); + image.dispose(); return { 'result': base64.encoder.convert(Uint8List.view(byteData!.buffer)), @@ -3141,7 +3156,7 @@ class _InspectorOverlayLayer extends Layer { _InspectorOverlayRenderState? _lastState; /// Picture generated from _lastState. - late ui.Picture _picture; + ui.Picture? _picture; TextPainter? _textPainter; double? _textPainterMaxWidth; @@ -3150,6 +3165,7 @@ class _InspectorOverlayLayer extends Layer { void dispose() { _textPainter?.dispose(); _textPainter = null; + _picture?.dispose(); super.dispose(); } @@ -3184,9 +3200,10 @@ class _InspectorOverlayLayer extends Layer { if (state != _lastState) { _lastState = state; + _picture?.dispose(); _picture = _buildPicture(state); } - builder.addPicture(Offset.zero, _picture); + builder.addPicture(Offset.zero, _picture!); } ui.Picture _buildPicture(_InspectorOverlayRenderState state) { diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index f0c56c262b5bd..a13638b5c6cba 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: material_color_utilities: 0.5.0 meta: 1.10.0 vector_math: 2.1.4 - web: 0.2.1-beta + web: 0.2.2-beta sky_engine: sdk: flutter @@ -22,8 +22,8 @@ dev_dependencies: flutter_goldens: sdk: flutter fake_async: 1.3.1 - leak_tracker: 9.0.7 - leak_tracker_flutter_testing: 1.0.5 + leak_tracker: 9.0.8 + leak_tracker_flutter_testing: 1.0.6 _fe_analyzer_shared: 64.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" analyzer: 6.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -74,4 +74,4 @@ dev_dependencies: webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: a796 +# PUBSPEC CHECKSUM: 9f99 diff --git a/packages/flutter/test/cupertino/dialog_test.dart b/packages/flutter/test/cupertino/dialog_test.dart index 7ae06059ca5dd..4ac91602d82a1 100644 --- a/packages/flutter/test/cupertino/dialog_test.dart +++ b/packages/flutter/test/cupertino/dialog_test.dart @@ -15,11 +15,12 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import '../widgets/semantics_tester.dart'; void main() { - testWidgets('Alert dialog control test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Alert dialog control test', (WidgetTester tester) async { bool didDelete = false; await tester.pumpWidget( @@ -58,7 +59,7 @@ void main() { expect(find.text('Delete'), findsNothing); }); - testWidgets('Dialog not barrier dismissible by default', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dialog not barrier dismissible by default', (WidgetTester tester) async { await tester.pumpWidget(createAppWithCenteredButton(const Text('Go'))); final BuildContext context = tester.element(find.text('Go')); @@ -86,7 +87,7 @@ void main() { }); - testWidgets('Dialog configurable to be barrier dismissible', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dialog configurable to be barrier dismissible', (WidgetTester tester) async { await tester.pumpWidget(createAppWithCenteredButton(const Text('Go'))); final BuildContext context = tester.element(find.text('Go')); @@ -114,7 +115,7 @@ void main() { expect(find.text('Dialog'), findsNothing); }); - testWidgets('Dialog destructive action style', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dialog destructive action style', (WidgetTester tester) async { await tester.pumpWidget(boilerplate(const CupertinoDialogAction( isDestructiveAction: true, child: Text('Ok'), @@ -125,7 +126,7 @@ void main() { expect(widget.style.color!.withAlpha(255), CupertinoColors.systemRed.color); }); - testWidgets('Dialog default action style', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dialog default action style', (WidgetTester tester) async { await tester.pumpWidget( CupertinoTheme( data: const CupertinoThemeData( @@ -142,7 +143,7 @@ void main() { expect(widget.style.color!.withAlpha(255), CupertinoColors.systemGreen.color); }); - testWidgets('Dialog dark theme', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dialog dark theme', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: MediaQuery( @@ -178,7 +179,7 @@ void main() { ); }); - testWidgets('Has semantic annotations', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Has semantic annotations', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget(const MaterialApp(home: Material( child: CupertinoAlertDialog( @@ -250,7 +251,7 @@ void main() { semantics.dispose(); }); - testWidgets('Dialog default action style', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dialog default action style', (WidgetTester tester) async { await tester.pumpWidget(boilerplate(const CupertinoDialogAction( isDefaultAction: true, child: Text('Ok'), @@ -261,7 +262,7 @@ void main() { expect(widget.style.fontWeight, equals(FontWeight.w600)); }); - testWidgets('Dialog default and destructive action styles', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dialog default and destructive action styles', (WidgetTester tester) async { await tester.pumpWidget(boilerplate(const CupertinoDialogAction( isDefaultAction: true, isDestructiveAction: true, @@ -274,7 +275,7 @@ void main() { expect(widget.style.fontWeight, equals(FontWeight.w600)); }); - testWidgets('Dialog disabled action style', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dialog disabled action style', (WidgetTester tester) async { await tester.pumpWidget(boilerplate(const CupertinoDialogAction( child: Text('Ok'), ))); @@ -285,7 +286,7 @@ void main() { expect(widget.style.color!.opacity, lessThanOrEqualTo(128 / 255)); }); - testWidgets('Dialog enabled action style', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dialog enabled action style', (WidgetTester tester) async { await tester.pumpWidget(boilerplate(CupertinoDialogAction( child: const Text('Ok'), onPressed: () {}, @@ -296,8 +297,9 @@ void main() { expect(widget.style.color!.opacity, equals(1.0)); }); - testWidgets('Message is scrollable, has correct padding with large text sizes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Message is scrollable, has correct padding with large text sizes', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( dialogBuilder: (BuildContext context) { @@ -352,8 +354,9 @@ void main() { expect(tester.getSize(find.widgetWithText(CupertinoDialogAction, 'OK')), equals(const Size(310.0, 98.0))); }); - testWidgets('Dialog respects small constraints.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dialog respects small constraints.', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( dialogBuilder: (BuildContext context) { @@ -397,8 +400,9 @@ void main() { ); }); - testWidgets('Button list is scrollable, has correct position with large text sizes.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Button list is scrollable, has correct position with large text sizes.', (WidgetTester tester) async { final ScrollController actionScrollController = ScrollController(); + addTearDown(actionScrollController.dispose); await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( dialogBuilder: (BuildContext context) { @@ -457,9 +461,10 @@ void main() { expect(tester.getSize(find.widgetWithText(CupertinoDialogAction, 'Cancel')).height, equals(148.0)); }); - testWidgets('Title Section is empty, Button section is not empty.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Title Section is empty, Button section is not empty.', (WidgetTester tester) async { const double textScaleFactor = 1.0; final ScrollController actionScrollController = ScrollController(); + addTearDown(actionScrollController.dispose); await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( dialogBuilder: (BuildContext context) { @@ -510,9 +515,10 @@ void main() { ); }); - testWidgets('Button section is empty, Title section is not empty.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Button section is empty, Title section is not empty.', (WidgetTester tester) async { const double textScaleFactor = 1.0; final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( dialogBuilder: (BuildContext context) { @@ -551,8 +557,9 @@ void main() { ); }); - testWidgets('Actions section height for 1 button is height of button.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Actions section height for 1 button is height of button.', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( dialogBuilder: (BuildContext context) { @@ -580,8 +587,9 @@ void main() { expect(okButtonBox.size.height, actionsSectionBox.size.height); }); - testWidgets('Actions section height for 2 side-by-side buttons is height of tallest button.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Actions section height for 2 side-by-side buttons is height of tallest button.', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); late double dividerWidth; // Will be set when the dialog builder runs. Needs a BuildContext. await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( @@ -625,8 +633,9 @@ void main() { ); }); - testWidgets('Actions section height for 2 stacked buttons with enough room is height of both buttons.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Actions section height for 2 stacked buttons with enough room is height of both buttons.', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); late double dividerThickness; // Will be set when the dialog builder runs. Needs a BuildContext. await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( @@ -667,8 +676,9 @@ void main() { ); }); - testWidgets('Actions section height for 2 stacked buttons without enough room and regular font is 1.5 buttons tall.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Actions section height for 2 stacked buttons without enough room and regular font is 1.5 buttons tall.', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( dialogBuilder: (BuildContext context) { @@ -701,8 +711,9 @@ void main() { ); }); - testWidgets('Actions section height for 2 stacked buttons without enough room and large accessibility font is 50% of dialog height.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Actions section height for 2 stacked buttons without enough room and large accessibility font is 50% of dialog height.', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( dialogBuilder: (BuildContext context) { @@ -741,8 +752,9 @@ void main() { ); }); - testWidgets('Actions section height for 3 buttons without enough room is 1.5 buttons tall.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Actions section height for 3 buttons without enough room is 1.5 buttons tall.', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( dialogBuilder: (BuildContext context) { @@ -785,8 +797,9 @@ void main() { ); }); - testWidgets('Actions section overscroll is painted white.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Actions section overscroll is painted white.', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( dialogBuilder: (BuildContext context) { @@ -833,8 +846,9 @@ void main() { )); }); - testWidgets('Pressed button changes appearance and dividers disappear.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Pressed button changes appearance and dividers disappear.', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); late double dividerThickness; // Will be set when the dialog builder runs. Needs a BuildContext. await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( @@ -946,7 +960,7 @@ void main() { await gesture.up(); }); - testWidgets('ScaleTransition animation for showCupertinoDialog()', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ScaleTransition animation for showCupertinoDialog()', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: Center( @@ -1024,7 +1038,7 @@ void main() { expect(find.byType(Transform), findsNothing); }); - testWidgets('FadeTransition animation for showCupertinoDialog()', (WidgetTester tester) async { + testWidgetsWithLeakTracking('FadeTransition animation for showCupertinoDialog()', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: Center( @@ -1117,7 +1131,7 @@ void main() { expect(transition.opacity.value, moreOrLessEquals(0.0, epsilon: 0.001)); }); - testWidgets('Actions are accessible by key', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Actions are accessible by key', (WidgetTester tester) async { await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( dialogBuilder: (BuildContext context) { @@ -1147,7 +1161,7 @@ void main() { expect(find.byKey(const Key('option_3')), findsNothing); }); - testWidgets('Dialog widget insets by MediaQuery viewInsets', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dialog widget insets by MediaQuery viewInsets', (WidgetTester tester) async { await tester.pumpWidget( const MaterialApp( home: MediaQuery( @@ -1177,7 +1191,7 @@ void main() { expect(tester.getRect(find.byType(Placeholder)), placeholderRectWithoutInsets.translate(10, 10)); }); - testWidgets('Material2 - Default cupertino dialog golden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material2 - Default cupertino dialog golden', (WidgetTester tester) async { await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( useMaterial3: false, @@ -1208,7 +1222,7 @@ void main() { ); }); - testWidgets('Material3 - Default cupertino dialog golden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material3 - Default cupertino dialog golden', (WidgetTester tester) async { await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( useMaterial3: true, @@ -1239,7 +1253,7 @@ void main() { ); }); - testWidgets('showCupertinoDialog - custom barrierLabel', (WidgetTester tester) async { + testWidgetsWithLeakTracking('showCupertinoDialog - custom barrierLabel', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( @@ -1279,7 +1293,7 @@ void main() { semantics.dispose(); }); - testWidgets('CupertinoDialogRoute is state restorable', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CupertinoDialogRoute is state restorable', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( restorationScopeId: 'app', @@ -1309,10 +1323,11 @@ void main() { expect(find.byType(CupertinoAlertDialog), findsOneWidget); }, skip: isBrowser); // https://github.com/flutter/flutter/issues/33615 - testWidgets('Conflicting scrollbars are not applied by ScrollBehavior to CupertinoAlertDialog', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Conflicting scrollbars are not applied by ScrollBehavior to CupertinoAlertDialog', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/83819 const double textScaleFactor = 1.0; final ScrollController actionScrollController = ScrollController(); + addTearDown(actionScrollController.dispose); await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( dialogBuilder: (BuildContext context) { @@ -1348,7 +1363,7 @@ void main() { expect(find.byType(CupertinoScrollbar), findsNWidgets(2)); }, variant: TargetPlatformVariant.all()); - testWidgets('CupertinoAlertDialog scrollbars controllers should be different', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CupertinoAlertDialog scrollbars controllers should be different', (WidgetTester tester) async { // https://github.com/flutter/flutter/pull/81278 await tester.pumpWidget( const MaterialApp( @@ -1375,7 +1390,7 @@ void main() { }); group('showCupertinoDialog avoids overlapping display features', () { - testWidgets('positioning using anchorPoint', (WidgetTester tester) async { + testWidgetsWithLeakTracking('positioning using anchorPoint', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( builder: (BuildContext context, Widget? child) { @@ -1413,7 +1428,7 @@ void main() { expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(800.0, 600.0)); }); - testWidgets('positioning using Directionality', (WidgetTester tester) async { + testWidgetsWithLeakTracking('positioning using Directionality', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( builder: (BuildContext context, Widget? child) { @@ -1453,7 +1468,7 @@ void main() { expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(800.0, 600.0)); }); - testWidgets('default positioning', (WidgetTester tester) async { + testWidgetsWithLeakTracking('default positioning', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( builder: (BuildContext context, Widget? child) { @@ -1491,7 +1506,7 @@ void main() { }); }); - testWidgets('Hovering over Cupertino alert dialog action updates cursor to clickable on Web', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Hovering over Cupertino alert dialog action updates cursor to clickable on Web', (WidgetTester tester) async { await tester.pumpWidget( createAppWithButtonThatLaunchesDialog( dialogBuilder: (BuildContext context) { diff --git a/packages/flutter/test/cupertino/magnifier_test.dart b/packages/flutter/test/cupertino/magnifier_test.dart index ffa160d035489..87c22f1b961fe 100644 --- a/packages/flutter/test/cupertino/magnifier_test.dart +++ b/packages/flutter/test/cupertino/magnifier_test.dart @@ -8,6 +8,7 @@ library; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { final Offset basicOffset = Offset(CupertinoMagnifier.kDefaultSize.width / 2, @@ -48,7 +49,7 @@ void main() { animatedPositioned.left ?? 0, animatedPositioned.top ?? 0); } - testWidgets('should be at gesture position if does not violate any positioning rules', (WidgetTester tester) async { + testWidgetsWithLeakTracking('should be at gesture position if does not violate any positioning rules', (WidgetTester tester) async { final Key fakeTextFieldKey = UniqueKey(); final Key outerKey = UniqueKey(); @@ -87,6 +88,7 @@ void main() { globalGesturePosition: fakeTextFieldRect.center, ), ); + addTearDown(magnifier.dispose); await showCupertinoMagnifier(context, tester, magnifier); @@ -98,7 +100,7 @@ void main() { ); }); - testWidgets('should never horizontally be outside of Screen Padding', (WidgetTester tester) async { + testWidgetsWithLeakTracking('should never horizontally be outside of Screen Padding', (WidgetTester tester) async { await tester.pumpWidget( const MaterialApp( color: Color.fromARGB(7, 0, 129, 90), @@ -108,19 +110,21 @@ void main() { final BuildContext context = tester.firstElement(find.byType(Placeholder)); + final ValueNotifier magnifierInfo = ValueNotifier( + MagnifierInfo( + currentLineBoundaries: reasonableTextField, + fieldBounds: reasonableTextField, + caretRect: reasonableTextField, + // The tap position is far out of the right side of the app. + globalGesturePosition: + Offset(MediaQuery.sizeOf(context).width + 100, 0), + ), + ); + addTearDown(magnifierInfo.dispose); await showCupertinoMagnifier( context, tester, - ValueNotifier( - MagnifierInfo( - currentLineBoundaries: reasonableTextField, - fieldBounds: reasonableTextField, - caretRect: reasonableTextField, - // The tap position is far out of the right side of the app. - globalGesturePosition: - Offset(MediaQuery.sizeOf(context).width + 100, 0), - ), - ), + magnifierInfo, ); // Should be less than the right edge, since we have padding. @@ -128,7 +132,7 @@ void main() { lessThan(MediaQuery.sizeOf(context).width)); }); - testWidgets('should have some vertical drag', (WidgetTester tester) async { + testWidgetsWithLeakTracking('should have some vertical drag', (WidgetTester tester) async { final double dragPositionBelowTextField = reasonableTextField.center.dy + 30; await tester.pumpWidget( @@ -141,20 +145,23 @@ void main() { final BuildContext context = tester.firstElement(find.byType(Placeholder)); + final ValueNotifier magnifierInfo = + ValueNotifier( + MagnifierInfo( + currentLineBoundaries: reasonableTextField, + fieldBounds: reasonableTextField, + caretRect: reasonableTextField, + // The tap position is dragBelow units below the text field. + globalGesturePosition: Offset( + MediaQuery.sizeOf(context).width / 2, + dragPositionBelowTextField), + ), + ); + addTearDown(magnifierInfo.dispose); await showCupertinoMagnifier( context, tester, - ValueNotifier( - MagnifierInfo( - currentLineBoundaries: reasonableTextField, - fieldBounds: reasonableTextField, - caretRect: reasonableTextField, - // The tap position is dragBelow units below the text field. - globalGesturePosition: Offset( - MediaQuery.sizeOf(context).width / 2, - dragPositionBelowTextField), - ), - ), + magnifierInfo, ); // The magnifier Y should be greater than the text field, since we "dragged" it down. @@ -166,7 +173,7 @@ void main() { }); group('status', () { - testWidgets('should hide if gesture is far below the text field', (WidgetTester tester) async { + testWidgetsWithLeakTracking('should hide if gesture is far below the text field', (WidgetTester tester) async { await tester.pumpWidget( const MaterialApp( color: Color.fromARGB(7, 0, 129, 90), @@ -177,7 +184,7 @@ void main() { final BuildContext context = tester.firstElement(find.byType(Placeholder)); - final ValueNotifier magnifierinfo = + final ValueNotifier magnifierInfo = ValueNotifier( MagnifierInfo( currentLineBoundaries: reasonableTextField, @@ -188,16 +195,17 @@ void main() { MediaQuery.sizeOf(context).width / 2, reasonableTextField.top), ), ); + addTearDown(magnifierInfo.dispose); // Show the magnifier initially, so that we get it in a not hidden state. - await showCupertinoMagnifier(context, tester, magnifierinfo); + await showCupertinoMagnifier(context, tester, magnifierInfo); // Move the gesture to one that should hide it. - magnifierinfo.value = MagnifierInfo( + magnifierInfo.value = MagnifierInfo( currentLineBoundaries: reasonableTextField, fieldBounds: reasonableTextField, caretRect: reasonableTextField, - globalGesturePosition: magnifierinfo.value.globalGesturePosition + const Offset(0, 100), + globalGesturePosition: magnifierInfo.value.globalGesturePosition + const Offset(0, 100), ); await tester.pumpAndSettle(); @@ -205,7 +213,7 @@ void main() { expect(magnifierController.overlayEntry, isNotNull); }); - testWidgets('should re-show if gesture moves back up', + testWidgetsWithLeakTracking('should re-show if gesture moves back up', (WidgetTester tester) async { await tester.pumpWidget( const MaterialApp( @@ -227,6 +235,7 @@ void main() { globalGesturePosition: Offset(MediaQuery.sizeOf(context).width / 2, reasonableTextField.top), ), ); + addTearDown(magnifierInfo.dispose); // Show the magnifier initially, so that we get it in a not hidden state. await showCupertinoMagnifier(context, tester, magnifierInfo); diff --git a/packages/flutter/test/cupertino/nav_bar_test.dart b/packages/flutter/test/cupertino/nav_bar_test.dart index fa6d3019993b2..f781805d799b0 100644 --- a/packages/flutter/test/cupertino/nav_bar_test.dart +++ b/packages/flutter/test/cupertino/nav_bar_test.dart @@ -11,13 +11,14 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import '../widgets/semantics_tester.dart'; int count = 0; void main() { - testWidgets('Middle still in center with asymmetrical actions', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Middle still in center with asymmetrical actions', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoNavigationBar( @@ -34,7 +35,7 @@ void main() { expect(tester.getCenter(find.text('Title')).dx, 400.0); }); - testWidgets('Middle still in center with back button', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Middle still in center with back button', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoNavigationBar( @@ -89,7 +90,7 @@ void main() { expect(find.byType(CupertinoNavigationBar), paints..rect(color: background.darkColor)); }); - testWidgets('Non-opaque background adds blur effects', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Non-opaque background adds blur effects', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoNavigationBar( @@ -100,7 +101,7 @@ void main() { expect(find.byType(BackdropFilter), findsOneWidget); }); - testWidgets('Nav bar displays correctly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Nav bar displays correctly', (WidgetTester tester) async { final GlobalKey navigator = GlobalKey(); await tester.pumpWidget( CupertinoApp( @@ -130,7 +131,7 @@ void main() { expect(tester.takeException(), isNull); }); - testWidgets('Can specify custom padding', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can specify custom padding', (WidgetTester tester) async { final Key middleBox = GlobalKey(); await tester.pumpWidget( CupertinoApp( @@ -187,7 +188,7 @@ void main() { } // Regression test for https://github.com/flutter/flutter/issues/119270 - testWidgets('System navigation bar properties are not overridden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('System navigation bar properties are not overridden', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoNavigationBar( @@ -198,7 +199,7 @@ void main() { expectSameStatusBarStyle(SystemChrome.latestStyle!, SystemUiOverlayStyle.dark); }); - testWidgets('Can specify custom brightness', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can specify custom brightness', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoNavigationBar( @@ -250,7 +251,7 @@ void main() { expectSameStatusBarStyle(SystemChrome.latestStyle!, SystemUiOverlayStyle.dark); }); - testWidgets('Padding works in RTL', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Padding works in RTL', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: Directionality( @@ -280,7 +281,7 @@ void main() { expect(tester.getCenter(find.text('Title')).dx, 400.0); }); - testWidgets('Nav bar uses theme defaults', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Nav bar uses theme defaults', (WidgetTester tester) async { count = 0x000000; await tester.pumpWidget( CupertinoApp( @@ -300,7 +301,7 @@ void main() { expect(count, 0x010101); }); - testWidgets('Nav bar respects themes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Nav bar respects themes', (WidgetTester tester) async { count = 0x000000; await tester.pumpWidget( CupertinoApp( @@ -321,7 +322,7 @@ void main() { expect(count, 0x010101); }); - testWidgets('Theme active color can be overridden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Theme active color can be overridden', (WidgetTester tester) async { count = 0x000000; await tester.pumpWidget( CupertinoApp( @@ -342,7 +343,7 @@ void main() { expect(count, 0x010101); }); - testWidgets('No slivers with no large titles', (WidgetTester tester) async { + testWidgetsWithLeakTracking('No slivers with no large titles', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoPageScaffold( @@ -357,8 +358,9 @@ void main() { expect(find.byType(SliverPersistentHeader), findsNothing); }); - testWidgets('Media padding is applied to CupertinoSliverNavigationBar', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Media padding is applied to CupertinoSliverNavigationBar', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); final Key leadingKey = GlobalKey(); final Key middleKey = GlobalKey(); final Key trailingKey = GlobalKey(); @@ -405,8 +407,9 @@ void main() { expect(tester.getTopLeft(find.byKey(titleKey)), const Offset(16.0 + 20.0, 54.0 + 10.0)); }); - testWidgets('Large title nav bar scrolls', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Large title nav bar scrolls', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( CupertinoApp( home: CupertinoPageScaffold( @@ -485,8 +488,9 @@ void main() { expect(tester.getSize(find.widgetWithText(ClipRect, 'Title').first).height, 0.0); }); - testWidgets('User specified middle is always visible in sliver', (WidgetTester tester) async { + testWidgetsWithLeakTracking('User specified middle is always visible in sliver', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); final Key segmentedControlsKey = UniqueKey(); await tester.pumpWidget( CupertinoApp( @@ -542,8 +546,9 @@ void main() { ); }); - testWidgets('User specified middle is only visible when sliver is collapsed if alwaysShowMiddle is false', (WidgetTester tester) async { + testWidgetsWithLeakTracking('User specified middle is only visible when sliver is collapsed if alwaysShowMiddle is false', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( CupertinoApp( home: CupertinoPageScaffold( @@ -588,8 +593,9 @@ void main() { expect(middleOpacity.opacity.value, 0.0); }); - testWidgets('Small title can be overridden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Small title can be overridden', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( CupertinoApp( home: CupertinoPageScaffold( @@ -652,7 +658,7 @@ void main() { expect(tester.getBottomLeft(find.text('Title')).dy, 44.0); // Extension gone. }); - testWidgets('Auto back/close button', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Auto back/close button', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoNavigationBar( @@ -707,7 +713,7 @@ void main() { expect(find.text('Home page'), findsOneWidget); }); - testWidgets('Long back label turns into "back"', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Long back label turns into "back"', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: Placeholder(), @@ -750,7 +756,7 @@ void main() { expect(find.widgetWithText(CupertinoButton, 'Back'), findsOneWidget); }); - testWidgets('Border should be displayed by default', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Border should be displayed by default', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoNavigationBar( @@ -772,7 +778,7 @@ void main() { expect(side, isNotNull); }); - testWidgets('Overrides border color', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Overrides border color', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoNavigationBar( @@ -801,7 +807,7 @@ void main() { expect(side.color, const Color(0xFFAABBCC)); }); - testWidgets('Border should not be displayed when null', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Border should not be displayed when null', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoNavigationBar( @@ -821,7 +827,7 @@ void main() { expect(decoration.border, isNull); }); - testWidgets('Border is displayed by default in sliver nav bar', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Border is displayed by default in sliver nav bar', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoPageScaffold( @@ -849,7 +855,7 @@ void main() { expect(bottom, isNotNull); }); - testWidgets('Border is not displayed when null in sliver nav bar', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Border is not displayed when null in sliver nav bar', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoPageScaffold( @@ -875,7 +881,7 @@ void main() { expect(decoration.border, isNull); }); - testWidgets('CupertinoSliverNavigationBar has semantics', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CupertinoSliverNavigationBar has semantics', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget(const CupertinoApp( @@ -900,7 +906,7 @@ void main() { semantics.dispose(); }); - testWidgets('CupertinoNavigationBar has semantics', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CupertinoNavigationBar has semantics', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget(CupertinoApp( @@ -921,7 +927,7 @@ void main() { semantics.dispose(); }); - testWidgets('Border can be overridden in sliver nav bar', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Border can be overridden in sliver nav bar', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoPageScaffold( @@ -959,7 +965,7 @@ void main() { expect(bottom.color, const Color(0xFFAABBCC)); }); - testWidgets( + testWidgetsWithLeakTracking( 'Standard title golden', (WidgetTester tester) async { await tester.pumpWidget( @@ -982,7 +988,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'Large title golden', (WidgetTester tester) async { await tester.pumpWidget( @@ -1013,7 +1019,7 @@ void main() { }, ); - testWidgets('NavBar draws a light system bar for a dark background', (WidgetTester tester) async { + testWidgetsWithLeakTracking('NavBar draws a light system bar for a dark background', (WidgetTester tester) async { await tester.pumpWidget( WidgetsApp( color: const Color(0xFFFFFFFF), @@ -1033,7 +1039,7 @@ void main() { expectSameStatusBarStyle(SystemChrome.latestStyle!, SystemUiOverlayStyle.light); }); - testWidgets('NavBar draws a dark system bar for a light background', (WidgetTester tester) async { + testWidgetsWithLeakTracking('NavBar draws a dark system bar for a light background', (WidgetTester tester) async { await tester.pumpWidget( WidgetsApp( color: const Color(0xFFFFFFFF), @@ -1053,7 +1059,7 @@ void main() { expectSameStatusBarStyle(SystemChrome.latestStyle!, SystemUiOverlayStyle.dark); }); - testWidgets('CupertinoNavigationBarBackButton shows an error when manually added outside a route', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CupertinoNavigationBarBackButton shows an error when manually added outside a route', (WidgetTester tester) async { await tester.pumpWidget(const CupertinoNavigationBarBackButton()); final dynamic exception = tester.takeException(); @@ -1061,7 +1067,7 @@ void main() { expect(exception.toString(), contains('CupertinoNavigationBarBackButton should only be used in routes that can be popped')); }); - testWidgets('CupertinoNavigationBarBackButton shows an error when placed in a route that cannot be popped', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CupertinoNavigationBarBackButton shows an error when placed in a route that cannot be popped', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoNavigationBarBackButton(), @@ -1073,7 +1079,7 @@ void main() { expect(exception.toString(), contains('CupertinoNavigationBarBackButton should only be used in routes that can be popped')); }); - testWidgets('CupertinoNavigationBarBackButton with a custom onPressed callback can be placed anywhere', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CupertinoNavigationBarBackButton with a custom onPressed callback can be placed anywhere', (WidgetTester tester) async { bool backPressed = false; await tester.pumpWidget( @@ -1092,7 +1098,7 @@ void main() { expect(backPressed, true); }); - testWidgets( + testWidgetsWithLeakTracking( 'Manually inserted CupertinoNavigationBarBackButton still automatically ' 'show previous page title when possible', (WidgetTester tester) async { @@ -1133,7 +1139,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'CupertinoNavigationBarBackButton onPressed overrides default pop behavior', (WidgetTester tester) async { bool backPressed = false; @@ -1188,7 +1194,7 @@ void main() { }, ); - testWidgets('textScaleFactor is set to 1.0', (WidgetTester tester) async { + testWidgetsWithLeakTracking('textScaleFactor is set to 1.0', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: Builder(builder: (BuildContext context) { @@ -1267,7 +1273,7 @@ void main() { expect(barItems2.any((RichText t) => t.textScaleFactor != 1), isFalse); }); - testWidgets( + testWidgetsWithLeakTracking( 'CupertinoSliverNavigationBar stretches upon over-scroll and bounces back once over-scroll ends', (WidgetTester tester) async { const Text trailingText = Text('Bar Button'); @@ -1322,7 +1328,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'CupertinoSliverNavigationBar does not stretch upon over-scroll if stretch parameter is false', (WidgetTester tester) async { const Text trailingText = Text('Bar Button'); @@ -1376,7 +1382,7 @@ void main() { }, ); - testWidgets('Null NavigationBar border transition', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Null NavigationBar border transition', (WidgetTester tester) async { // This is a regression test for https://github.com/flutter/flutter/issues/71389 await tester.pumpWidget( const CupertinoApp( @@ -1416,7 +1422,7 @@ void main() { expect(find.text('Page 2'), findsNothing); }); - testWidgets( + testWidgetsWithLeakTracking( 'CupertinoSliverNavigationBar magnifies upon over-scroll and shrinks back once over-scroll ends', (WidgetTester tester) async { const Text titleText = Text('Large Title'); @@ -1474,7 +1480,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'CupertinoSliverNavigationBar large title text does not get clipped when magnified', (WidgetTester tester) async { const Text titleText = Text('Very very very long large title'); @@ -1521,10 +1527,11 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'CupertinoSliverNavigationBar large title can be hit tested when magnified', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( CupertinoApp( diff --git a/packages/flutter/test/cupertino/nav_bar_transition_test.dart b/packages/flutter/test/cupertino/nav_bar_transition_test.dart index 662fcb5300c6c..97205e3e1cd08 100644 --- a/packages/flutter/test/cupertino/nav_bar_transition_test.dart +++ b/packages/flutter/test/cupertino/nav_bar_transition_test.dart @@ -11,6 +11,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; Future startTransitionBetween( WidgetTester tester, { @@ -131,7 +132,7 @@ void checkOpacity(WidgetTester tester, Finder finder, double opacity) { } void main() { - testWidgets('Bottom middle moves between middle and back label', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Bottom middle moves between middle and back label', (WidgetTester tester) async { await startTransitionBetween(tester, fromTitle: 'Page 1'); // Be mid-transition. @@ -159,7 +160,7 @@ void main() { ); }); - testWidgets('Bottom middle moves between middle and back label RTL', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Bottom middle moves between middle and back label RTL', (WidgetTester tester) async { await startTransitionBetween( tester, fromTitle: 'Page 1', @@ -186,7 +187,7 @@ void main() { ); }); - testWidgets('Bottom middle never changes size during the animation', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Bottom middle never changes size during the animation', (WidgetTester tester) async { await tester.binding.setSurfaceSize(const Size(1080.0 / 2.75, 600)); addTearDown(() async { await tester.binding.setSurfaceSize(const Size(800.0, 600.0)); @@ -207,7 +208,7 @@ void main() { } }); - testWidgets('Bottom middle and top back label transitions their font', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Bottom middle and top back label transitions their font', (WidgetTester tester) async { await startTransitionBetween(tester, fromTitle: 'Page 1'); // Be mid-transition. @@ -251,7 +252,7 @@ void main() { checkOpacity(tester, flying(tester, find.text('Page 1')).last, 0.5292819738388062); }); - testWidgets('Font transitions respect themes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Font transitions respect themes', (WidgetTester tester) async { await startTransitionBetween( tester, fromTitle: 'Page 1', @@ -299,7 +300,7 @@ void main() { checkOpacity(tester, flying(tester, find.text('Page 1')).last, 0.5292819738388062); }); - testWidgets('Fullscreen dialogs do not create heroes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Fullscreen dialogs do not create heroes', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: Placeholder(), @@ -333,7 +334,7 @@ void main() { expect(() => flying(tester, find.text('Page 2')), throwsAssertionError); }); - testWidgets('Turning off transition works', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Turning off transition works', (WidgetTester tester) async { await startTransitionBetween( tester, from: const CupertinoNavigationBar( @@ -357,7 +358,7 @@ void main() { expect(() => flying(tester, find.text('Page 2')), throwsAssertionError); }); - testWidgets('Popping mid-transition is symmetrical', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Popping mid-transition is symmetrical', (WidgetTester tester) async { await startTransitionBetween(tester, fromTitle: 'Page 1'); // Be mid-transition. @@ -405,7 +406,7 @@ void main() { checkColorAndPositionAt50ms(); }); - testWidgets('Popping mid-transition is symmetrical RTL', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Popping mid-transition is symmetrical RTL', (WidgetTester tester) async { await startTransitionBetween( tester, fromTitle: 'Page 1', @@ -456,7 +457,7 @@ void main() { checkColorAndPositionAt50ms(); }); - testWidgets('There should be no global keys in the hero flight', (WidgetTester tester) async { + testWidgetsWithLeakTracking('There should be no global keys in the hero flight', (WidgetTester tester) async { await startTransitionBetween(tester, fromTitle: 'Page 1'); // Be mid-transition. @@ -471,7 +472,7 @@ void main() { ); }); - testWidgets('DartPerformanceMode is latency mid-animation', (WidgetTester tester) async { + testWidgetsWithLeakTracking('DartPerformanceMode is latency mid-animation', (WidgetTester tester) async { DartPerformanceMode? mode; // before the animation starts, no requests are active. @@ -491,7 +492,7 @@ void main() { expect(mode, isNull); }); - testWidgets('Multiple nav bars tags do not conflict if in different navigators', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Multiple nav bars tags do not conflict if in different navigators', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: CupertinoTabScaffold( @@ -566,7 +567,7 @@ void main() { expect(find.text('Tab 1 Page 2', skipOffstage: false), findsNothing); }); - testWidgets('Transition box grows to large title size', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transition box grows to large title size', (WidgetTester tester) async { await startTransitionBetween( tester, fromTitle: 'Page 1', @@ -590,7 +591,7 @@ void main() { checkBackgroundBoxHeight(tester, 84.33018499612808); }); - testWidgets('Large transition box shrinks to standard nav bar size', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Large transition box shrinks to standard nav bar size', (WidgetTester tester) async { await startTransitionBetween( tester, from: const CupertinoSliverNavigationBar(), @@ -614,7 +615,7 @@ void main() { checkBackgroundBoxHeight(tester, 55.66981500387192); }); - testWidgets('Hero flight removed at the end of page transition', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Hero flight removed at the end of page transition', (WidgetTester tester) async { await startTransitionBetween(tester, fromTitle: 'Page 1'); await tester.pump(const Duration(milliseconds: 50)); @@ -629,7 +630,7 @@ void main() { expect(() => flying(tester, find.text('Page 1')), throwsAssertionError); }); - testWidgets('Exact widget is reused to build inside the transition', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Exact widget is reused to build inside the transition', (WidgetTester tester) async { const Widget userMiddle = Placeholder(); await startTransitionBetween( tester, @@ -645,7 +646,7 @@ void main() { expect(flying(tester, find.byWidget(userMiddle)), findsOneWidget); }); - testWidgets('Middle is not shown if alwaysShowMiddle is false and the nav bar is expanded', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Middle is not shown if alwaysShowMiddle is false and the nav bar is expanded', (WidgetTester tester) async { const Widget userMiddle = Placeholder(); await startTransitionBetween( tester, @@ -662,9 +663,10 @@ void main() { expect(flying(tester, find.byWidget(userMiddle)), findsNothing); }); - testWidgets('Middle is shown if alwaysShowMiddle is false but the nav bar is collapsed', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Middle is shown if alwaysShowMiddle is false but the nav bar is collapsed', (WidgetTester tester) async { const Widget userMiddle = Placeholder(); final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( CupertinoApp( @@ -710,7 +712,7 @@ void main() { expect(flying(tester, find.byWidget(userMiddle)), findsOneWidget); }); - testWidgets('First appearance of back chevron fades in from the right', (WidgetTester tester) async { + testWidgetsWithLeakTracking('First appearance of back chevron fades in from the right', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: scaffoldForNavBar(null), @@ -749,7 +751,7 @@ void main() { )); }); - testWidgets('First appearance of back chevron fades in from the left in RTL', (WidgetTester tester) async { + testWidgetsWithLeakTracking('First appearance of back chevron fades in from the left in RTL', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( builder: (BuildContext context, Widget? navigator) { @@ -801,7 +803,7 @@ void main() { ); }); - testWidgets('Back chevron fades out and in when both pages have it', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Back chevron fades out and in when both pages have it', (WidgetTester tester) async { await startTransitionBetween(tester, fromTitle: 'Page 1'); await tester.pump(const Duration(milliseconds: 50)); @@ -827,7 +829,7 @@ void main() { expect(tester.getTopLeft(backChevrons.last), const Offset(14.0, 7.0)); }); - testWidgets('Bottom middle just fades if top page has a custom leading', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Bottom middle just fades if top page has a custom leading', (WidgetTester tester) async { await startTransitionBetween( tester, fromTitle: 'Page 1', @@ -858,7 +860,7 @@ void main() { ); }); - testWidgets('Bottom leading fades in place', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Bottom leading fades in place', (WidgetTester tester) async { await startTransitionBetween( tester, from: const CupertinoSliverNavigationBar(leading: Text('custom')), @@ -884,7 +886,7 @@ void main() { ); }); - testWidgets('Bottom trailing fades in place', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Bottom trailing fades in place', (WidgetTester tester) async { await startTransitionBetween( tester, from: const CupertinoSliverNavigationBar(trailing: Text('custom')), @@ -916,7 +918,7 @@ void main() { ); }); - testWidgets('Bottom back label fades and slides to the left', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Bottom back label fades and slides to the left', (WidgetTester tester) async { await startTransitionBetween( tester, fromTitle: 'Page 1', @@ -958,7 +960,7 @@ void main() { ); }); - testWidgets('Bottom back label fades and slides to the right in RTL', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Bottom back label fades and slides to the right in RTL', (WidgetTester tester) async { await startTransitionBetween( tester, fromTitle: 'Page 1', @@ -1002,7 +1004,7 @@ void main() { ); }); - testWidgets('Bottom large title moves to top back label', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Bottom large title moves to top back label', (WidgetTester tester) async { await startTransitionBetween( tester, from: const CupertinoSliverNavigationBar(), @@ -1054,7 +1056,7 @@ void main() { ); }); - testWidgets('Long title turns into the word back mid transition', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Long title turns into the word back mid transition', (WidgetTester tester) async { await startTransitionBetween( tester, from: const CupertinoSliverNavigationBar(), @@ -1104,7 +1106,7 @@ void main() { ); }); - testWidgets('Bottom large title and top back label transitions their font', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Bottom large title and top back label transitions their font', (WidgetTester tester) async { await startTransitionBetween( tester, from: const CupertinoSliverNavigationBar(), @@ -1143,7 +1145,7 @@ void main() { expect(topBackLabel.text.style!.letterSpacing, moreOrLessEquals(-0.2259759941697121)); }); - testWidgets('Top middle fades in and slides in from the right', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Top middle fades in and slides in from the right', (WidgetTester tester) async { await startTransitionBetween( tester, toTitle: 'Page 2', @@ -1174,7 +1176,7 @@ void main() { ); }); - testWidgets('Top middle never changes size during the animation', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Top middle never changes size during the animation', (WidgetTester tester) async { await tester.binding.setSurfaceSize(const Size(1080.0 / 2.75, 600)); addTearDown(() async { await tester.binding.setSurfaceSize(const Size(800.0, 600.0)); @@ -1198,7 +1200,7 @@ void main() { } }); - testWidgets('Top middle fades in and slides in from the left in RTL', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Top middle fades in and slides in from the left in RTL', (WidgetTester tester) async { await startTransitionBetween( tester, toTitle: 'Page 2', @@ -1230,7 +1232,7 @@ void main() { ); }); - testWidgets('Top large title fades in and slides in from the right', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Top large title fades in and slides in from the right', (WidgetTester tester) async { await startTransitionBetween( tester, to: const CupertinoSliverNavigationBar(), @@ -1256,7 +1258,7 @@ void main() { ); }); - testWidgets('Top large title fades in and slides in from the left in RTL', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Top large title fades in and slides in from the left in RTL', (WidgetTester tester) async { await startTransitionBetween( tester, to: const CupertinoSliverNavigationBar(), @@ -1283,7 +1285,7 @@ void main() { ); }); - testWidgets('Components are not unnecessarily rebuilt during transitions', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Components are not unnecessarily rebuilt during transitions', (WidgetTester tester) async { int bottomBuildTimes = 0; int topBuildTimes = 0; await startTransitionBetween( @@ -1328,7 +1330,7 @@ void main() { expect(topBuildTimes, 3); }); - testWidgets('Back swipe gesture transitions', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Back swipe gesture transitions', (WidgetTester tester) async { await startTransitionBetween( tester, fromTitle: 'Page 1', @@ -1391,7 +1393,7 @@ void main() { expect(find.text('Page 1'), findsOneWidget); }); - testWidgets('textScaleFactor is set to 1.0 on transition', (WidgetTester tester) async { + testWidgetsWithLeakTracking('textScaleFactor is set to 1.0 on transition', (WidgetTester tester) async { await startTransitionBetween(tester, fromTitle: 'Page 1', textScale: 99); await tester.pump(const Duration(milliseconds: 50)); @@ -1399,7 +1401,7 @@ void main() { expect(tester.firstWidget(flying(tester, find.byType(RichText))).textScaleFactor, 1); }); - testWidgets('Back swipe gesture cancels properly with transition', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Back swipe gesture cancels properly with transition', (WidgetTester tester) async { await startTransitionBetween( tester, fromTitle: 'Page 1', diff --git a/packages/flutter/test/cupertino/page_test.dart b/packages/flutter/test/cupertino/page_test.dart index ceb80e4427e72..7fbed63b517d6 100644 --- a/packages/flutter/test/cupertino/page_test.dart +++ b/packages/flutter/test/cupertino/page_test.dart @@ -4,9 +4,10 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { - testWidgets('test iOS page transition (LTR)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('test iOS page transition (LTR)', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( onGenerateRoute: (RouteSettings settings) { @@ -79,7 +80,7 @@ void main() { expect(widget1InitialTopLeft, equals(widget1TransientTopLeft)); }); - testWidgets('test iOS page transition (RTL)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('test iOS page transition (RTL)', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( localizationsDelegates: const >[ @@ -150,7 +151,7 @@ void main() { expect(widget1InitialTopLeft, equals(widget1TransientTopLeft)); }); - testWidgets('test iOS fullscreen dialog transition', (WidgetTester tester) async { + testWidgetsWithLeakTracking('test iOS fullscreen dialog transition', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: Center(child: Text('Page 1')), @@ -210,7 +211,7 @@ void main() { expect(widget1InitialTopLeft, equals(widget1TransientTopLeft)); }); - testWidgets('test only edge swipes work (LTR)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('test only edge swipes work (LTR)', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( onGenerateRoute: (RouteSettings settings) { @@ -271,7 +272,7 @@ void main() { expect(find.text('Page 2'), isOnstage); }); - testWidgets('test edge swipes work with media query padding (LTR)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('test edge swipes work with media query padding (LTR)', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( builder: (BuildContext context, Widget? navigator) { @@ -315,7 +316,7 @@ void main() { expect(find.text('Page 2'), isOnstage); }); - testWidgets('test edge swipes work with media query padding (RLT)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('test edge swipes work with media query padding (RLT)', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( builder: (BuildContext context, Widget? navigator) { @@ -363,7 +364,7 @@ void main() { expect(find.text('Page 2'), isOnstage); }); - testWidgets('test only edge swipes work (RTL)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('test only edge swipes work (RTL)', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( localizationsDelegates: const >[ @@ -428,7 +429,7 @@ void main() { expect(find.text('Page 2'), isOnstage); }); - testWidgets('test edge swipe then drop back at starting point works', (WidgetTester tester) async { + testWidgetsWithLeakTracking('test edge swipe then drop back at starting point works', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( onGenerateRoute: (RouteSettings settings) { @@ -463,7 +464,7 @@ void main() { expect(find.text('Page 2'), isOnstage); }); - testWidgets('CupertinoPage does not lose its state when transitioning out', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CupertinoPage does not lose its state when transitioning out', (WidgetTester tester) async { final GlobalKey navigator = GlobalKey(); await tester.pumpWidget(KeepsStateTestWidget(navigatorKey: navigator)); expect(find.text('subpage'), findsOneWidget); @@ -476,7 +477,7 @@ void main() { expect(find.text('home'), findsOneWidget); }); - testWidgets('CupertinoPage restores its state', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CupertinoPage restores its state', (WidgetTester tester) async { await tester.pumpWidget( RootRestorationScope( restorationId: 'root', @@ -610,6 +611,12 @@ class _TestRestorableWidgetState extends State with Restor registerForRestoration(counter, 'counter'); } + @override + void dispose() { + super.dispose(); + counter.dispose(); + } + @override Widget build(BuildContext context) { return Column( diff --git a/packages/flutter/test/cupertino/radio_test.dart b/packages/flutter/test/cupertino/radio_test.dart index 0a7d3460c3ea2..da62e4c6baf6f 100644 --- a/packages/flutter/test/cupertino/radio_test.dart +++ b/packages/flutter/test/cupertino/radio_test.dart @@ -7,11 +7,12 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import '../widgets/semantics_tester.dart'; void main() { - testWidgets('Radio control test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Radio control test', (WidgetTester tester) async { final Key key = UniqueKey(); final List log = []; @@ -63,7 +64,7 @@ void main() { expect(log, isEmpty); }); - testWidgets('Radio can be toggled when toggleable is set', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Radio can be toggled when toggleable is set', (WidgetTester tester) async { final Key key = UniqueKey(); final List log = []; @@ -118,7 +119,7 @@ void main() { expect(log, equals([1])); }); - testWidgets('Radio selected semantics - platform adaptive', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Radio selected semantics - platform adaptive', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget(CupertinoApp( @@ -153,7 +154,7 @@ void main() { semantics.dispose(); }, variant: TargetPlatformVariant.all()); - testWidgets('Radio semantics', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Radio semantics', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget(CupertinoApp( @@ -241,7 +242,7 @@ void main() { semantics.dispose(); }); - testWidgets('has semantic events', (WidgetTester tester) async { + testWidgetsWithLeakTracking('has semantic events', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); final Key key = UniqueKey(); dynamic semanticEvent; @@ -278,13 +279,14 @@ void main() { tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler(SystemChannels.accessibility, null); }); - testWidgets('Radio can be controlled by keyboard shortcuts', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Radio can be controlled by keyboard shortcuts', (WidgetTester tester) async { tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; int? groupValue = 1; const Key radioKey0 = Key('radio0'); const Key radioKey1 = Key('radio1'); const Key radioKey2 = Key('radio2'); final FocusNode focusNode2 = FocusNode(debugLabel: 'radio2'); + addTearDown(focusNode2.dispose); Widget buildApp({bool enabled = true}) { return CupertinoApp( home: Center( @@ -350,7 +352,7 @@ void main() { expect(groupValue, equals(2)); }); - testWidgets('Show a checkmark when useCheckmarkStyle is true', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Show a checkmark when useCheckmarkStyle is true', (WidgetTester tester) async { await tester.pumpWidget(CupertinoApp( home: Center( child: CupertinoRadio( @@ -405,7 +407,7 @@ void main() { ); }); - testWidgets('Do not crash when widget disappears while pointer is down', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Do not crash when widget disappears while pointer is down', (WidgetTester tester) async { final Key key = UniqueKey(); Widget buildRadio(bool show) { diff --git a/packages/flutter/test/cupertino/scaffold_test.dart b/packages/flutter/test/cupertino/scaffold_test.dart index 2dd4f74dd374a..35abbfe4f84c9 100644 --- a/packages/flutter/test/cupertino/scaffold_test.dart +++ b/packages/flutter/test/cupertino/scaffold_test.dart @@ -6,12 +6,13 @@ import 'dart:typed_data'; import 'package:flutter/cupertino.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import '../image_data.dart'; /// Integration tests testing both [CupertinoPageScaffold] and [CupertinoTabScaffold]. void main() { - testWidgets('Contents are behind translucent bar', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Contents are behind translucent bar', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoPageScaffold( @@ -27,7 +28,7 @@ void main() { expect(tester.getTopLeft(find.byType(Center)), Offset.zero); }); - testWidgets('Opaque bar pushes contents down', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Opaque bar pushes contents down', (WidgetTester tester) async { late BuildContext childContext; await tester.pumpWidget(Directionality( textDirection: TextDirection.ltr, @@ -102,7 +103,7 @@ void main() { expect(find.byType(CupertinoPageScaffold), paints..rect(color: backgroundColor.darkColor)); }); - testWidgets('Contents padding from viewInsets', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Contents padding from viewInsets', (WidgetTester tester) async { await tester.pumpWidget(Directionality( textDirection: TextDirection.ltr, child: MediaQuery( @@ -160,7 +161,7 @@ void main() { expect(tester.getSize(find.byType(Container)).height, 600.0); }); - testWidgets('Contents bottom padding are not consumed by viewInsets when resizeToAvoidBottomInset overridden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Contents bottom padding are not consumed by viewInsets when resizeToAvoidBottomInset overridden', (WidgetTester tester) async { const Widget child = CupertinoPageScaffold( resizeToAvoidBottomInset: false, navigationBar: CupertinoNavigationBar( @@ -198,7 +199,7 @@ void main() { expect(initialPoint, finalPoint); }); - testWidgets('Contents are between opaque bars', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Contents are between opaque bars', (WidgetTester tester) async { const Center page1Center = Center(); await tester.pumpWidget( @@ -235,7 +236,7 @@ void main() { expect(tester.getSize(find.byWidget(page1Center)).height, 600.0 - 44.0 - 50.0); }); - testWidgets('Contents have automatic sliver padding between translucent bars', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Contents have automatic sliver padding between translucent bars', (WidgetTester tester) async { const SizedBox content = SizedBox(height: 600.0, width: 600.0); await tester.pumpWidget( @@ -289,7 +290,7 @@ void main() { expect(tester.getBottomLeft(find.byWidget(content)).dy, 600 - 20.0 - 50.0); }); - testWidgets('iOS independent tab navigation', (WidgetTester tester) async { + testWidgetsWithLeakTracking('iOS independent tab navigation', (WidgetTester tester) async { // A full on iOS information architecture app with 2 tabs, and 2 pages // in each with independent navigation states. await tester.pumpWidget( @@ -398,7 +399,7 @@ void main() { expect(find.text('Page 2 of tab 1', skipOffstage: false), isOffstage); }); - testWidgets('Decorated with white background by default', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Decorated with white background by default', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoPageScaffold( @@ -414,7 +415,7 @@ void main() { expect(decoration.color, isSameColorAs(CupertinoColors.white)); }); - testWidgets('Overrides background color', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Overrides background color', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoPageScaffold( @@ -431,7 +432,7 @@ void main() { expect(decoration.color, const Color(0xFF010203)); }); - testWidgets('Lists in CupertinoPageScaffold scroll to the top when status bar tapped', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Lists in CupertinoPageScaffold scroll to the top when status bar tapped', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( builder: (BuildContext context, Widget? child) { @@ -483,7 +484,7 @@ void main() { expect(find.text('12'), findsNothing); }); - testWidgets('resizeToAvoidBottomInset is supported even when no navigationBar', (WidgetTester tester) async { + testWidgetsWithLeakTracking('resizeToAvoidBottomInset is supported even when no navigationBar', (WidgetTester tester) async { Widget buildFrame(bool showNavigationBar, bool showKeyboard) { return CupertinoApp( home: MediaQuery( @@ -528,7 +529,7 @@ void main() { expect(positionWithInsetNoNavBar, equals(positionWithInsetWithNavBar)); }); - testWidgets('textScaleFactor is set to 1.0', (WidgetTester tester) async { + testWidgetsWithLeakTracking('textScaleFactor is set to 1.0', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: Builder(builder: (BuildContext context) { diff --git a/packages/flutter/test/cupertino/scrollbar_test.dart b/packages/flutter/test/cupertino/scrollbar_test.dart index e8a1277ef7494..702a3ca8c8180 100644 --- a/packages/flutter/test/cupertino/scrollbar_test.dart +++ b/packages/flutter/test/cupertino/scrollbar_test.dart @@ -8,6 +8,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; const CupertinoDynamicColor _kScrollbarColor = CupertinoDynamicColor.withBrightness( color: Color(0x59000000), @@ -20,7 +21,7 @@ void main() { const Duration kScrollbarResizeDuration = Duration(milliseconds: 100); const Duration kLongPressDuration = Duration(milliseconds: 100); - testWidgets('Scrollbar never goes away until finger lift', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Scrollbar never goes away until finger lift', (WidgetTester tester) async { await tester.pumpWidget( const Directionality( textDirection: TextDirection.ltr, @@ -58,7 +59,7 @@ void main() { )); }); - testWidgets('Scrollbar dark mode', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Scrollbar dark mode', (WidgetTester tester) async { Brightness brightness = Brightness.light; late StateSetter setState; await tester.pumpWidget( @@ -95,8 +96,9 @@ void main() { )); }); - testWidgets('Scrollbar thumb can be dragged with long press', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Scrollbar thumb can be dragged with long press', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -167,8 +169,9 @@ void main() { await tester.pump(kScrollbarFadeDuration); }); - testWidgets('Scrollbar thumb can be dragged with long press - reverse', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Scrollbar thumb can be dragged with long press - reverse', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -242,7 +245,7 @@ void main() { await tester.pump(kScrollbarFadeDuration); }); - testWidgets('Scrollbar changes thickness and radius when dragged', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Scrollbar changes thickness and radius when dragged', (WidgetTester tester) async { const double thickness = 20; const double thicknessWhileDragging = 40; const double radius = 10; @@ -253,6 +256,7 @@ void main() { final Size screenSize = tester.view.physicalSize / tester.view.devicePixelRatio; final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -339,7 +343,7 @@ void main() { await tester.pump(kScrollbarFadeDuration); }); - testWidgets('When thumbVisibility is true, must pass a controller or find PrimaryScrollController', (WidgetTester tester) async { + testWidgetsWithLeakTracking('When thumbVisibility is true, must pass a controller or find PrimaryScrollController', (WidgetTester tester) async { Widget viewWithScroll() { return const Directionality( textDirection: TextDirection.ltr, @@ -364,8 +368,9 @@ void main() { }, ); - testWidgets('When thumbVisibility is true, must pass a controller or find PrimaryScrollController that is attached to a scroll view', (WidgetTester tester) async { + testWidgetsWithLeakTracking('When thumbVisibility is true, must pass a controller or find PrimaryScrollController that is attached to a scroll view', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); Widget viewWithScroll() { return Directionality( textDirection: TextDirection.ltr, @@ -398,7 +403,7 @@ void main() { }, ); - testWidgets('When thumbVisibility is true, must pass a controller or find PrimaryScrollController', (WidgetTester tester) async { + testWidgetsWithLeakTracking('When thumbVisibility is true, must pass a controller or find PrimaryScrollController', (WidgetTester tester) async { Widget viewWithScroll() { return const Directionality( textDirection: TextDirection.ltr, @@ -423,8 +428,9 @@ void main() { }, ); - testWidgets('When thumbVisibility is true, must pass a controller or find PrimaryScrollController that is attached to a scroll view', (WidgetTester tester) async { + testWidgetsWithLeakTracking('When thumbVisibility is true, must pass a controller or find PrimaryScrollController that is attached to a scroll view', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); Widget viewWithScroll() { return Directionality( textDirection: TextDirection.ltr, @@ -457,8 +463,9 @@ void main() { }, ); - testWidgets('On first render with thumbVisibility: true, the thumb shows with PrimaryScrollController', (WidgetTester tester) async { + testWidgetsWithLeakTracking('On first render with thumbVisibility: true, the thumb shows with PrimaryScrollController', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); Widget viewWithScroll() { return Directionality( textDirection: TextDirection.ltr, @@ -491,8 +498,9 @@ void main() { }, ); - testWidgets('On first render with thumbVisibility: true, the thumb shows', (WidgetTester tester) async { + testWidgetsWithLeakTracking('On first render with thumbVisibility: true, the thumb shows', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); Widget viewWithScroll() { return Directionality( textDirection: TextDirection.ltr, @@ -524,8 +532,9 @@ void main() { expect(find.byType(CupertinoScrollbar), paints..rrect()); }); - testWidgets('On first render with thumbVisibility: true, the thumb shows with PrimaryScrollController', (WidgetTester tester) async { + testWidgetsWithLeakTracking('On first render with thumbVisibility: true, the thumb shows with PrimaryScrollController', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); Widget viewWithScroll() { return Directionality( textDirection: TextDirection.ltr, @@ -558,8 +567,9 @@ void main() { }, ); - testWidgets('On first render with thumbVisibility: true, the thumb shows', (WidgetTester tester) async { + testWidgetsWithLeakTracking('On first render with thumbVisibility: true, the thumb shows', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); Widget viewWithScroll() { return Directionality( textDirection: TextDirection.ltr, @@ -591,8 +601,9 @@ void main() { expect(find.byType(CupertinoScrollbar), paints..rrect()); }); - testWidgets('On first render with thumbVisibility: false, the thumb is hidden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('On first render with thumbVisibility: false, the thumb is hidden', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); Widget viewWithScroll() { return Directionality( textDirection: TextDirection.ltr, @@ -619,8 +630,9 @@ void main() { expect(find.byType(CupertinoScrollbar), isNot(paints..rect())); }); - testWidgets('With thumbVisibility: true, fling a scroll. While it is still scrolling, set thumbVisibility: false. The thumb should not fade out until the scrolling stops.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('With thumbVisibility: true, fling a scroll. While it is still scrolling, set thumbVisibility: false. The thumb should not fade out until the scrolling stops.', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); bool thumbVisibility = true; Widget viewWithScroll() { return StatefulBuilder( @@ -676,10 +688,11 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'With thumbVisibility: false, set thumbVisibility: true. The thumb should be always shown directly', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); bool thumbVisibility = false; Widget viewWithScroll() { return StatefulBuilder( @@ -730,11 +743,12 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'With thumbVisibility: false, fling a scroll. While it is still scrolling, set thumbVisibility: true. ' 'The thumb should not fade even after the scrolling stops', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); bool thumbVisibility = false; Widget viewWithScroll() { return StatefulBuilder( @@ -797,11 +811,12 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'Toggling thumbVisibility while not scrolling fades the thumb in/out. ' 'This works even when you have never scrolled at all yet', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); bool thumbVisibility = true; Widget viewWithScroll() { return StatefulBuilder( @@ -852,8 +867,9 @@ void main() { }, ); - testWidgets('Scrollbar thumb can be dragged with long press - horizontal axis', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Scrollbar thumb can be dragged with long press - horizontal axis', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -926,8 +942,9 @@ void main() { await tester.pump(kScrollbarFadeDuration); }); - testWidgets('Scrollbar thumb can be dragged with long press - horizontal axis, reverse', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Scrollbar thumb can be dragged with long press - horizontal axis, reverse', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -1001,8 +1018,9 @@ void main() { await tester.pump(kScrollbarFadeDuration); }); - testWidgets('Tapping the track area pages the Scroll View', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Tapping the track area pages the Scroll View', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -1060,8 +1078,9 @@ void main() { ); }); - testWidgets('Throw if interactive with the bar when no position attached', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Throw if interactive with the bar when no position attached', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( Directionality( @@ -1104,9 +1123,11 @@ void main() { FlutterError.onError = handler; }); - testWidgets('Interactive scrollbars should have a valid scroll controller', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Interactive scrollbars should have a valid scroll controller', (WidgetTester tester) async { final ScrollController primaryScrollController = ScrollController(); + addTearDown(primaryScrollController.dispose); final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( Directionality( @@ -1145,9 +1166,10 @@ void main() { ); }); - testWidgets('Simultaneous dragging and pointer scrolling does not cause a crash', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Simultaneous dragging and pointer scrolling does not cause a crash', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/70105 final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( CupertinoApp( home: PrimaryScrollController( @@ -1256,8 +1278,9 @@ void main() { ); }); - testWidgets('CupertinoScrollbar scrollOrientation works correctly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CupertinoScrollbar scrollOrientation works correctly', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( CupertinoApp( diff --git a/packages/flutter/test/cupertino/sliding_segmented_control_test.dart b/packages/flutter/test/cupertino/sliding_segmented_control_test.dart index 08bc09205760d..3aece48a8aedd 100644 --- a/packages/flutter/test/cupertino/sliding_segmented_control_test.dart +++ b/packages/flutter/test/cupertino/sliding_segmented_control_test.dart @@ -9,6 +9,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import '../widgets/semantics_tester.dart'; @@ -93,7 +94,7 @@ void main() { groupValue = 0; }); - testWidgets('Need at least 2 children', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Need at least 2 children', (WidgetTester tester) async { groupValue = null; await expectLater( () => tester.pumpWidget( @@ -146,7 +147,7 @@ void main() { ); }); - testWidgets('Padding works', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Padding works', (WidgetTester tester) async { const Key key = Key('Container'); const Map children = { @@ -223,7 +224,7 @@ void main() { await verifyPadding(padding: const EdgeInsets.fromLTRB(1, 3, 5, 7)); }); - testWidgets('Tap changes toggle state', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Tap changes toggle state', (WidgetTester tester) async { const Map children = { 0: Text('Child 1'), 1: Text('Child 2'), @@ -255,7 +256,7 @@ void main() { expect(groupValue, 1); }); - testWidgets( + testWidgetsWithLeakTracking( 'Segmented controls respect theme', (WidgetTester tester) async { const Map children = { @@ -293,7 +294,7 @@ void main() { }, ); - testWidgets('SegmentedControl dark mode', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SegmentedControl dark mode', (WidgetTester tester) async { const Map children = { 0: Text('Child 1'), 1: Icon(IconData(1)), @@ -345,7 +346,7 @@ void main() { expect(decorationDark.color!.value, CupertinoColors.systemRed.darkColor.value); }); - testWidgets( + testWidgetsWithLeakTracking( 'Children can be non-Text or Icon widgets (in this case, ' 'a Container or Placeholder widget)', (WidgetTester tester) async { @@ -369,13 +370,13 @@ void main() { }, ); - testWidgets('Passed in value is child initially selected', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Passed in value is child initially selected', (WidgetTester tester) async { await tester.pumpWidget(setupSimpleSegmentedControl()); expect(getHighlightedIndex(tester), 0); }); - testWidgets('Null input for value results in no child initially selected', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Null input for value results in no child initially selected', (WidgetTester tester) async { const Map children = { 0: Text('Child 1'), 1: Text('Child 2'), @@ -401,7 +402,7 @@ void main() { expect(getHighlightedIndex(tester), null); }); - testWidgets('Long press not-selected child interactions', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Long press not-selected child interactions', (WidgetTester tester) async { const Map children = { 0: Text('Child 1'), 1: Text('Child 2'), @@ -465,7 +466,7 @@ void main() { expect(getChildOpacityByName('Child 2'), 0.2); }); - testWidgets('Long press does not change the opacity of currently-selected child', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Long press does not change the opacity of currently-selected child', (WidgetTester tester) async { double getChildOpacityByName(String childName) { return tester.renderObject( find.ancestor(matching: find.byType(AnimatedOpacity), of: find.text(childName)), @@ -482,7 +483,7 @@ void main() { expect(getChildOpacityByName('Child 1'), 1); }); - testWidgets('Height of segmented control is determined by tallest widget', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Height of segmented control is determined by tallest widget', (WidgetTester tester) async { final Map children = { 0: Container(constraints: const BoxConstraints.tightFor(height: 100.0)), 1: Container(constraints: const BoxConstraints.tightFor(height: 400.0)), @@ -512,7 +513,7 @@ void main() { ); }); - testWidgets('Width of each segmented control segment is determined by widest widget', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Width of each segmented control segment is determined by widest widget', (WidgetTester tester) async { final Map children = { 0: Container(constraints: const BoxConstraints.tightFor(width: 50.0)), 1: Container(constraints: const BoxConstraints.tightFor(width: 100.0)), @@ -543,7 +544,7 @@ void main() { expect(childWidth, 200.0 + 9.25 * 2); }); - testWidgets('Width is finite in unbounded space', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Width is finite in unbounded space', (WidgetTester tester) async { const Map children = { 0: SizedBox(width: 50), 1: SizedBox(width: 70), @@ -576,7 +577,7 @@ void main() { ); }); - testWidgets('Directionality test - RTL should reverse order of widgets', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Directionality test - RTL should reverse order of widgets', (WidgetTester tester) async { const Map children = { 0: Text('Child 1'), 1: Text('Child 2'), @@ -603,7 +604,7 @@ void main() { expect(tester.getTopRight(find.text('Child 1')).dx > tester.getTopRight(find.text('Child 2')).dx, isTrue); }); - testWidgets('Correct initial selection and toggling behavior - RTL', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Correct initial selection and toggling behavior - RTL', (WidgetTester tester) async { const Map children = { 0: Text('Child 1'), 1: Text('Child 2'), @@ -640,7 +641,7 @@ void main() { expect(getHighlightedIndex(tester), 0); }); - testWidgets('Segmented control semantics', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Segmented control semantics', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); const Map children = { 0: Text('Child 1'), @@ -733,7 +734,7 @@ void main() { semantics.dispose(); }); - testWidgets('Non-centered taps work on smaller widgets', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Non-centered taps work on smaller widgets', (WidgetTester tester) async { final Map children = {}; children[0] = const Text('Child 1'); children[1] = const SizedBox(); @@ -761,7 +762,7 @@ void main() { expect(groupValue, 1); }); - testWidgets('Hit-tests report accurate local position in segments', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Hit-tests report accurate local position in segments', (WidgetTester tester) async { final Map children = {}; late TapDownDetails tapDownDetails; children[0] = GestureDetector( @@ -793,7 +794,7 @@ void main() { expect(tapDownDetails.globalPosition, segment0GlobalOffset + const Offset(7, 11)); }); - testWidgets('Thumb animation is correct when the selected segment changes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Thumb animation is correct when the selected segment changes', (WidgetTester tester) async { await tester.pumpWidget(setupSimpleSegmentedControl()); final Rect initialRect = currentUnscaledThumbRect(tester, useGlobalCoordinate: true); @@ -874,7 +875,7 @@ void main() { expect(currentThumbScale(tester), moreOrLessEquals(1, epsilon: 0.01)); }); - testWidgets( + testWidgetsWithLeakTracking( 'Thumb does not go out of bounds in animation', (WidgetTester tester) async { const Map children = { @@ -931,7 +932,7 @@ void main() { }, ); - testWidgets('Transition is triggered while a transition is already occurring', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transition is triggered while a transition is already occurring', (WidgetTester tester) async { const Map children = { 0: Text('A'), 1: Text('B'), @@ -981,7 +982,7 @@ void main() { ); }); - testWidgets('Insert segment while animation is running', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Insert segment while animation is running', (WidgetTester tester) async { final Map children = SplayTreeMap((int a, int b) => a - b); children[0] = const Text('A'); @@ -1027,7 +1028,7 @@ void main() { ); }); - testWidgets('change selection programmatically when dragging', (WidgetTester tester) async { + testWidgetsWithLeakTracking('change selection programmatically when dragging', (WidgetTester tester) async { const Map children = { 0: Text('A'), 1: Text('B'), @@ -1086,7 +1087,7 @@ void main() { expect(callbackCalled, isFalse); }); - testWidgets('Disallow new gesture when dragging', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Disallow new gesture when dragging', (WidgetTester tester) async { const Map children = { 0: Text('A'), 1: Text('B'), @@ -1141,7 +1142,7 @@ void main() { expect(callbackCalled, isFalse); }); - testWidgets('gesture outlives the widget', (WidgetTester tester) async { + testWidgetsWithLeakTracking('gesture outlives the widget', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/63338. const Map children = { 0: Text('A'), @@ -1179,7 +1180,7 @@ void main() { expect(tester.takeException(), isNull); }); - testWidgets('computeDryLayout is pure', (WidgetTester tester) async { + testWidgetsWithLeakTracking('computeDryLayout is pure', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/73362. const Map children = { 0: Text('A'), @@ -1213,7 +1214,7 @@ void main() { expect(tester.takeException(), isNull); }); - testWidgets('Has consistent size, independent of groupValue', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Has consistent size, independent of groupValue', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/62063. const Map children = { 0: Text('A'), @@ -1247,12 +1248,13 @@ void main() { } }); - testWidgets('ScrollView + SlidingSegmentedControl interaction', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ScrollView + SlidingSegmentedControl interaction', (WidgetTester tester) async { const Map children = { 0: Text('Child 1'), 1: Text('Child 2'), }; final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( Directionality( @@ -1333,7 +1335,7 @@ void main() { expect(groupValue, 1); }); - testWidgets('Hovering over Cupertino sliding segmented control updates cursor to clickable on Web', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Hovering over Cupertino sliding segmented control updates cursor to clickable on Web', (WidgetTester tester) async { const Map children = { 0: Text('A'), 1: Text('BB'), diff --git a/packages/flutter/test/cupertino/spell_check_suggestions_toolbar_test.dart b/packages/flutter/test/cupertino/spell_check_suggestions_toolbar_test.dart index dec2165a6c80f..fa88e2859d8b4 100644 --- a/packages/flutter/test/cupertino/spell_check_suggestions_toolbar_test.dart +++ b/packages/flutter/test/cupertino/spell_check_suggestions_toolbar_test.dart @@ -7,11 +7,12 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - testWidgets('more than three suggestions throws an error', (WidgetTester tester) async { + testWidgetsWithLeakTracking('more than three suggestions throws an error', (WidgetTester tester) async { Future pumpToolbar(List suggestions) async { await tester.pumpWidget( CupertinoApp( @@ -61,10 +62,14 @@ void main() { expect(labels, isNot(contains('yeller'))); }); - testWidgets('buildButtonItems builds a disabled "No Replacements Found" button when no suggestions', (WidgetTester tester) async { + testWidgetsWithLeakTracking('buildButtonItems builds a disabled "No Replacements Found" button when no suggestions', (WidgetTester tester) async { + final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); + final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); await tester.pumpWidget( CupertinoApp( - home: _FakeEditableText(), + home: _FakeEditableText(focusNode, controller), ), ); final _FakeEditableTextState editableTextState = @@ -80,9 +85,11 @@ void main() { } class _FakeEditableText extends EditableText { - _FakeEditableText() : super( - controller: TextEditingController(), - focusNode: FocusNode(), + /// The parameters focusNode and controller are needed here so the can be + /// safely disposed after the test is completed. + _FakeEditableText(FocusNode focusNode, TextEditingController controller) : super( + controller: controller, + focusNode: focusNode, backgroundCursorColor: CupertinoColors.white, cursorColor: CupertinoColors.white, style: const TextStyle(), diff --git a/packages/flutter/test/cupertino/switch_test.dart b/packages/flutter/test/cupertino/switch_test.dart index e6b484bda281e..cf4962c03773d 100644 --- a/packages/flutter/test/cupertino/switch_test.dart +++ b/packages/flutter/test/cupertino/switch_test.dart @@ -14,9 +14,10 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { - testWidgets('Switch can toggle on tap', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch can toggle on tap', (WidgetTester tester) async { final Key switchKey = UniqueKey(); bool value = false; await tester.pumpWidget( @@ -46,7 +47,7 @@ void main() { expect(value, isTrue); }); - testWidgets('CupertinoSwitch can be toggled by keyboard shortcuts', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CupertinoSwitch can be toggled by keyboard shortcuts', (WidgetTester tester) async { bool value = true; Widget buildApp({bool enabled = true}) { return CupertinoApp( @@ -79,7 +80,7 @@ void main() { expect(value, isTrue); }); - testWidgets('Switch emits light haptic vibration on tap', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch emits light haptic vibration on tap', (WidgetTester tester) async { final Key switchKey = UniqueKey(); bool value = false; @@ -119,7 +120,7 @@ void main() { expect(log.single, isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact')); }, variant: TargetPlatformVariant.only(TargetPlatform.iOS)); - testWidgets('Using other widgets that rebuild the switch will not cause vibrations', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Using other widgets that rebuild the switch will not cause vibrations', (WidgetTester tester) async { final Key switchKey = UniqueKey(); final Key switchKey2 = UniqueKey(); bool value = false; @@ -190,7 +191,7 @@ void main() { expect(log[3], isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact')); }, variant: TargetPlatformVariant.only(TargetPlatform.iOS)); - testWidgets('Haptic vibration triggers on drag', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Haptic vibration triggers on drag', (WidgetTester tester) async { bool value = false; final List log = []; @@ -228,7 +229,7 @@ void main() { expect(log[0], isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact')); }, variant: TargetPlatformVariant.only(TargetPlatform.iOS)); - testWidgets('No haptic vibration triggers from a programmatic value change', (WidgetTester tester) async { + testWidgetsWithLeakTracking('No haptic vibration triggers from a programmatic value change', (WidgetTester tester) async { final Key switchKey = UniqueKey(); bool value = false; @@ -280,7 +281,7 @@ void main() { expect(log, hasLength(0)); }, variant: TargetPlatformVariant.only(TargetPlatform.iOS)); - testWidgets('Switch can drag (LTR)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch can drag (LTR)', (WidgetTester tester) async { bool value = false; await tester.pumpWidget( @@ -324,7 +325,7 @@ void main() { expect(value, isFalse); }); - testWidgets('Switch can drag with dragStartBehavior', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch can drag with dragStartBehavior', (WidgetTester tester) async { bool value = false; await tester.pumpWidget( @@ -410,7 +411,7 @@ void main() { await tester.pump(); }); - testWidgets('Switch can drag (RTL)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch can drag (RTL)', (WidgetTester tester) async { bool value = false; await tester.pumpWidget( @@ -455,7 +456,7 @@ void main() { expect(value, isFalse); }); - testWidgets('can veto switch dragging result', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can veto switch dragging result', (WidgetTester tester) async { bool value = false; await tester.pumpWidget( @@ -527,7 +528,7 @@ void main() { expect(position.value, 1.0); }); - testWidgets('Switch is translucent when disabled', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch is translucent when disabled', (WidgetTester tester) async { await tester.pumpWidget( const Directionality( textDirection: TextDirection.ltr, @@ -545,7 +546,7 @@ void main() { expect(tester.widget(find.byType(Opacity).first).opacity, 0.5); }); - testWidgets('Switch is using track color when set', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch is using track color when set', (WidgetTester tester) async { const Color trackColor = Color(0xFF00FF00); await tester.pumpWidget( @@ -567,7 +568,7 @@ void main() { expect(find.byType(CupertinoSwitch), paints..rrect(color: trackColor)); }); - testWidgets('Switch is using default thumb color', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch is using default thumb color', (WidgetTester tester) async { await tester.pumpWidget( const Directionality( textDirection: TextDirection.ltr, @@ -593,7 +594,7 @@ void main() { ); }); - testWidgets('Switch is using thumb color when set', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch is using thumb color when set', (WidgetTester tester) async { const Color thumbColor = Color(0xFF000000); await tester.pumpWidget( const Directionality( @@ -621,7 +622,7 @@ void main() { ); }); - testWidgets('Switch is opaque when enabled', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch is opaque when enabled', (WidgetTester tester) async { await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -639,7 +640,7 @@ void main() { expect(tester.widget(find.byType(Opacity).first).opacity, 1.0); }); - testWidgets('Switch turns translucent after becoming disabled', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch turns translucent after becoming disabled', (WidgetTester tester) async { await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -670,7 +671,7 @@ void main() { expect(tester.widget(find.byType(Opacity).first).opacity, 0.5); }); - testWidgets('Switch turns opaque after becoming enabled', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch turns opaque after becoming enabled', (WidgetTester tester) async { await tester.pumpWidget( const Directionality( textDirection: TextDirection.ltr, @@ -701,7 +702,7 @@ void main() { expect(tester.widget(find.byType(Opacity).first).opacity, 1.0); }); - testWidgets('Switch renders correctly before, during, and after being tapped', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch renders correctly before, during, and after being tapped', (WidgetTester tester) async { final Key switchKey = UniqueKey(); bool value = false; await tester.pumpWidget( @@ -779,7 +780,7 @@ void main() { style: PaintingStyle.stroke, ); - testWidgets('Switch renders switch labels correctly before, during, and after being tapped', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch renders switch labels correctly before, during, and after being tapped', (WidgetTester tester) async { final Key switchKey = UniqueKey(); bool value = false; await tester.pumpWidget( @@ -829,7 +830,7 @@ void main() { expect(switchRenderObject, offLabelPaintPattern(alpha: 0)); }); - testWidgets('Switch renders switch labels correctly before, during, and after being tapped in high contrast', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch renders switch labels correctly before, during, and after being tapped in high contrast', (WidgetTester tester) async { final Key switchKey = UniqueKey(); bool value = false; await tester.pumpWidget( @@ -882,7 +883,7 @@ void main() { expect(switchRenderObject, offLabelPaintPattern(highContrast: true, alpha: 0)); }); - testWidgets('Switch renders switch labels correctly before, during, and after being tapped with direction rtl', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch renders switch labels correctly before, during, and after being tapped with direction rtl', (WidgetTester tester) async { final Key switchKey = UniqueKey(); bool value = false; await tester.pumpWidget( @@ -932,7 +933,7 @@ void main() { expect(switchRenderObject, offLabelPaintPattern(isRtl: true, alpha: 0)); }); - testWidgets('Switch renders correctly in dark mode', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch renders correctly in dark mode', (WidgetTester tester) async { final Key switchKey = UniqueKey(); bool value = false; await tester.pumpWidget( @@ -977,7 +978,7 @@ void main() { ); }); - testWidgets('Switch can apply the ambient theme and be opted out', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Switch can apply the ambient theme and be opted out', (WidgetTester tester) async { final Key switchKey = UniqueKey(); bool value = false; await tester.pumpWidget( @@ -1037,7 +1038,7 @@ void main() { ); }); - testWidgets('Hovering over Cupertino switch updates cursor to clickable on Web', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Hovering over Cupertino switch updates cursor to clickable on Web', (WidgetTester tester) async { const bool value = false; // Disabled CupertinoSwitch does not update cursor on Web. await tester.pumpWidget( @@ -1093,8 +1094,9 @@ void main() { ); }); - testWidgets('CupertinoSwitch is focusable and has correct focus color', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CupertinoSwitch is focusable and has correct focus color', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(debugLabel: 'CupertinoSwitch'); + addTearDown(focusNode.dispose); tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; bool value = true; const Color focusColor = Color(0xffff0000); @@ -1174,8 +1176,9 @@ void main() { ); }); - testWidgets('CupertinoSwitch.onFocusChange callback', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CupertinoSwitch.onFocusChange callback', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(debugLabel: 'CupertinoSwitch'); + addTearDown(focusNode.dispose); bool focused = false; await tester.pumpWidget( Directionality( diff --git a/packages/flutter/test/cupertino/tab_scaffold_test.dart b/packages/flutter/test/cupertino/tab_scaffold_test.dart index 22270d83f0792..ea03c5423d2e0 100644 --- a/packages/flutter/test/cupertino/tab_scaffold_test.dart +++ b/packages/flutter/test/cupertino/tab_scaffold_test.dart @@ -6,6 +6,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import '../image_data.dart'; import '../rendering/rendering_tester.dart' show TestCallbackPainter; @@ -50,7 +51,7 @@ void main() { ); } - testWidgets('Tab switching', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Tab switching', (WidgetTester tester) async { final List tabsPainted = []; await tester.pumpWidget( @@ -104,7 +105,7 @@ void main() { expect(selectedTabs, const [1, 0]); }); - testWidgets('Tabs are lazy built and moved offstage when inactive', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Tabs are lazy built and moved offstage when inactive', (WidgetTester tester) async { final List tabsBuilt = []; await tester.pumpWidget( @@ -139,12 +140,15 @@ void main() { expect(find.text('Page 2', skipOffstage: false), isOffstage); }); - testWidgets('Last tab gets focus', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Last tab gets focus', (WidgetTester tester) async { // 2 nodes for 2 tabs final List focusNodes = [ FocusNode(debugLabel: 'Node 1'), FocusNode(debugLabel: 'Node 2'), ]; + for (final FocusNode focusNode in focusNodes) { + addTearDown(focusNode.dispose); + } await tester.pumpWidget( CupertinoApp( @@ -175,13 +179,16 @@ void main() { expect(focusNodes[1].hasFocus, isFalse); }); - testWidgets('Do not affect focus order in the route', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Do not affect focus order in the route', (WidgetTester tester) async { final List focusNodes = [ FocusNode(debugLabel: 'Node 1'), FocusNode(debugLabel: 'Node 2'), FocusNode(debugLabel: 'Node 3'), FocusNode(debugLabel: 'Node 4'), ]; + for (final FocusNode focusNode in focusNodes) { + addTearDown(focusNode.dispose); + } await tester.pumpWidget( CupertinoApp( @@ -238,8 +245,9 @@ void main() { ); }); - testWidgets('Programmatic tab switching by changing the index of an existing controller', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Programmatic tab switching by changing the index of an existing controller', (WidgetTester tester) async { final CupertinoTabController controller = CupertinoTabController(initialIndex: 1); + addTearDown(controller.dispose); final List tabsPainted = []; await tester.pumpWidget( @@ -276,7 +284,7 @@ void main() { expect(selectedTabs, const [1]); }); - testWidgets('Programmatic tab switching by passing in a new controller', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Programmatic tab switching by passing in a new controller', (WidgetTester tester) async { final List tabsPainted = []; await tester.pumpWidget( @@ -297,11 +305,13 @@ void main() { expect(tabsPainted, const [0]); + final CupertinoTabController controller = CupertinoTabController(initialIndex: 1); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: CupertinoTabScaffold( tabBar: _buildTabBar(), - controller: CupertinoTabController(initialIndex: 1), // Programmatically change the tab now. + controller: controller, // Programmatically change the tab now. tabBuilder: (BuildContext context, int index) { return CustomPaint( painter: TestCallbackPainter( @@ -326,7 +336,7 @@ void main() { expect(selectedTabs, const [0]); }); - testWidgets('Tab bar respects themes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Tab bar respects themes', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: CupertinoTabScaffold( @@ -384,7 +394,7 @@ void main() { expect(tab2.text.style!.color, isSameColorAs(CupertinoColors.systemRed.darkColor)); }); - testWidgets('Tab contents are padded when there are view insets', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Tab contents are padded when there are view insets', (WidgetTester tester) async { late BuildContext innerContext; await tester.pumpWidget( @@ -410,7 +420,7 @@ void main() { expect(MediaQuery.of(innerContext).padding.bottom, 0); }); - testWidgets('Tab contents are not inset when resizeToAvoidBottomInset overridden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Tab contents are not inset when resizeToAvoidBottomInset overridden', (WidgetTester tester) async { late BuildContext innerContext; await tester.pumpWidget( @@ -437,7 +447,7 @@ void main() { expect(MediaQuery.of(innerContext).padding.bottom, 50); }); - testWidgets('Tab contents bottom padding are not consumed by viewInsets when resizeToAvoidBottomInset overridden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Tab contents bottom padding are not consumed by viewInsets when resizeToAvoidBottomInset overridden', (WidgetTester tester) async { final Widget child = Localizations( locale: const Locale('en', 'US'), delegates: const >[ @@ -485,7 +495,7 @@ void main() { expect(initialPoint, finalPoint); }); - testWidgets( + testWidgetsWithLeakTracking( 'Opaque tab bar consumes bottom padding while non opaque tab bar does not', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/43581. @@ -517,7 +527,7 @@ void main() { }, ); - testWidgets('Tab and page scaffolds do not double stack view insets', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Tab and page scaffolds do not double stack view insets', (WidgetTester tester) async { late BuildContext innerContext; await tester.pumpWidget( @@ -547,7 +557,7 @@ void main() { expect(MediaQuery.of(innerContext).padding.bottom, 0); }); - testWidgets('Deleting tabs after selecting them should switch to the last available tab', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Deleting tabs after selecting them should switch to the last available tab', (WidgetTester tester) async { final List tabsBuilt = []; await tester.pumpWidget( @@ -617,9 +627,10 @@ void main() { }); // Regression test for https://github.com/flutter/flutter/issues/33455 - testWidgets('Adding new tabs does not crash the app', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Adding new tabs does not crash the app', (WidgetTester tester) async { final List tabsPainted = []; final CupertinoTabController controller = CupertinoTabController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -671,13 +682,14 @@ void main() { expect(tabsPainted, const [0, 0, 18]); }); - testWidgets( + testWidgetsWithLeakTracking( 'If a controller is initially provided then the parent stops doing so for rebuilds, ' 'a new instance of CupertinoTabController should be created and used by the widget, ' "while preserving the previous controller's tab index", (WidgetTester tester) async { final List tabsPainted = []; final CupertinoTabController oldController = CupertinoTabController(); + addTearDown(oldController.dispose); await tester.pumpWidget( CupertinoApp( @@ -735,11 +747,12 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'Do not call dispose on a controller that we do not own ' 'but do remove from its listeners when done listening to it', (WidgetTester tester) async { final MockCupertinoTabController mockController = MockCupertinoTabController(initialIndex: 0); + addTearDown(mockController.dispose); await tester.pumpWidget( CupertinoApp( @@ -772,7 +785,7 @@ void main() { }, ); - testWidgets('The owner can dispose the old controller', (WidgetTester tester) async { + testWidgetsWithLeakTracking('The owner can dispose the old controller', (WidgetTester tester) async { CupertinoTabController controller = CupertinoTabController(initialIndex: 2); await tester.pumpWidget( @@ -792,6 +805,7 @@ void main() { controller.dispose(); controller = CupertinoTabController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: CupertinoTabScaffold( @@ -810,7 +824,7 @@ void main() { expect(find.text('Tab 3'), findsNothing); }); - testWidgets('A controller can control more than one CupertinoTabScaffold, ' + testWidgetsWithLeakTracking('A controller can control more than one CupertinoTabScaffold, ' 'removal of listeners does not break the controller', (WidgetTester tester) async { final List tabsPainted0 = []; @@ -893,7 +907,9 @@ void main() { expect(controller.numOfListeners, 1); // Replacing controller works. + controller.dispose(); controller = MockCupertinoTabController(initialIndex: 2); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: CupertinoPageScaffold( @@ -923,8 +939,9 @@ void main() { }, ); - testWidgets('Assert when current tab index >= number of tabs', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Assert when current tab index >= number of tabs', (WidgetTester tester) async { final CupertinoTabController controller = CupertinoTabController(initialIndex: 2); + addTearDown(controller.dispose); try { await tester.pumpWidget( @@ -964,10 +981,16 @@ void main() { expect(message, contains('with 3 tabs')); }); - testWidgets("Don't replace focus nodes for existing tabs when changing tab count", (WidgetTester tester) async { + testWidgetsWithLeakTracking("Don't replace focus nodes for existing tabs when changing tab count", (WidgetTester tester) async { final CupertinoTabController controller = CupertinoTabController(initialIndex: 2); + addTearDown(controller.dispose); - final List scopes = List.filled(5, FocusScopeNode()); + final List scopes = []; + for (int i = 0; i < 5; i++) { + final FocusScopeNode scope = FocusScopeNode(); + addTearDown(scope.dispose); + scopes.add(scope); + } await tester.pumpWidget( CupertinoApp( home: CupertinoTabScaffold( @@ -1013,7 +1036,7 @@ void main() { expect(scopes.sublist(0, 3), equals(newScopes.sublist(0, 3))); }); - testWidgets('Current tab index cannot go below zero or be null', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Current tab index cannot go below zero or be null', (WidgetTester tester) async { void expectAssertionError(VoidCallback callback, String errorMessage) { try { callback(); @@ -1025,11 +1048,12 @@ void main() { expectAssertionError(() => CupertinoTabController(initialIndex: -1), '>= 0'); final CupertinoTabController controller = CupertinoTabController(); + addTearDown(controller.dispose); expectAssertionError(() => controller.index = -1, '>= 0'); }); - testWidgets('Does not lose state when focusing on text input', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Does not lose state when focusing on text input', (WidgetTester tester) async { // Regression testing for https://github.com/flutter/flutter/issues/28457. await tester.pumpWidget( @@ -1071,7 +1095,7 @@ void main() { expect(find.text("don't lose me"), findsOneWidget); }); - testWidgets('textScaleFactor is set to 1.0', (WidgetTester tester) async { + testWidgetsWithLeakTracking('textScaleFactor is set to 1.0', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: Builder(builder: (BuildContext context) { @@ -1113,7 +1137,7 @@ void main() { expect(contents, isNot(contains(predicate((RichText t) => t.textScaler != const TextScaler.linear(99.0))))); }); - testWidgets('state restoration', (WidgetTester tester) async { + testWidgetsWithLeakTracking('state restoration', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( restorationScopeId: 'app', @@ -1168,7 +1192,7 @@ void main() { expect(find.text('Content 3'), findsNothing); }); - testWidgets('switch from internal to external controller with state restoration', (WidgetTester tester) async { + testWidgetsWithLeakTracking('switch from internal to external controller with state restoration', (WidgetTester tester) async { Widget buildWidget({CupertinoTabController? controller}) { return CupertinoApp( restorationScopeId: 'app', @@ -1202,6 +1226,7 @@ void main() { expect(find.text('Content 3'), findsNothing); final CupertinoTabController controller = CupertinoTabController(initialIndex: 3); + addTearDown(controller.dispose); await tester.pumpWidget(buildWidget(controller: controller)); expect(find.text('Content 0'), findsNothing); @@ -1242,7 +1267,7 @@ void main() { .setMockMethodCallHandler(SystemChannels.platform, null); }); - testWidgets('System back navigation inside of tabs', (WidgetTester tester) async { + testWidgetsWithLeakTracking('System back navigation inside of tabs', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: MediaQuery( diff --git a/packages/flutter/test/cupertino/text_field_test.dart b/packages/flutter/test/cupertino/text_field_test.dart index fe4a90fc084ba..147dcc355430a 100644 --- a/packages/flutter/test/cupertino/text_field_test.dart +++ b/packages/flutter/test/cupertino/text_field_test.dart @@ -17,6 +17,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import '../widgets/clipboard_utils.dart'; import '../widgets/editable_text_utils.dart' show OverflowWidgetTextEditingController; @@ -208,15 +209,17 @@ void main() { }); - testWidgets( + testWidgetsWithLeakTracking( 'Live Text button shows and hides correctly when LiveTextStatus changes', (WidgetTester tester) async { final LiveTextInputTester liveTextInputTester = LiveTextInputTester(); addTearDown(liveTextInputTester.dispose); final TextEditingController controller = TextEditingController(text: ''); + addTearDown(controller.dispose); const Key key = ValueKey('TextField'); final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); final Widget app = MaterialApp( theme: ThemeData(platform: TargetPlatform.iOS), home: Scaffold( @@ -250,7 +253,7 @@ void main() { }, ); - testWidgets('Look Up shows up on iOS only', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Look Up shows up on iOS only', (WidgetTester tester) async { String? lastLookUp; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async { @@ -264,6 +267,7 @@ void main() { final TextEditingController controller = TextEditingController( text: 'Test', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -299,7 +303,7 @@ void main() { skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu. ); - testWidgets('Search Web shows up on iOS only', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Search Web shows up on iOS only', (WidgetTester tester) async { String? lastSearch; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async { @@ -313,6 +317,7 @@ void main() { final TextEditingController controller = TextEditingController( text: 'Test', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -348,7 +353,7 @@ void main() { skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu. ); - testWidgets('Share shows up on iOS only', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Share shows up on iOS only', (WidgetTester tester) async { String? lastShare; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async { @@ -362,6 +367,7 @@ void main() { final TextEditingController controller = TextEditingController( text: 'Test', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -397,10 +403,11 @@ void main() { skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu. ); - testWidgets('can use the desktop cut/copy/paste buttons on Mac', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can use the desktop cut/copy/paste buttons on Mac', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'blah1 blah2', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -472,11 +479,13 @@ void main() { skip: kIsWeb, // [intended] the web handles this on its own. ); - testWidgets('can get text selection color initially on desktop', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can get text selection color initially on desktop', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); final TextEditingController controller = TextEditingController( text: 'blah1 blah2', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -502,10 +511,11 @@ void main() { ); }); - testWidgets('Activates the text field when receives semantics focus on Mac, Windows', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Activates the text field when receives semantics focus on Mac, Windows', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!; final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); await tester.pumpWidget( CupertinoApp( home: CupertinoTextField(focusNode: focusNode), @@ -552,7 +562,7 @@ void main() { semantics.dispose(); }, variant: const TargetPlatformVariant({ TargetPlatform.macOS, TargetPlatform.windows })); - testWidgets( + testWidgetsWithLeakTracking( 'takes available space horizontally and takes intrinsic space vertically no-strut', (WidgetTester tester) async { await tester.pumpWidget( @@ -573,7 +583,7 @@ void main() { }, ); - testWidgets('sets cursorOpacityAnimates on EditableText correctly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('sets cursorOpacityAnimates on EditableText correctly', (WidgetTester tester) async { // True @@ -598,7 +608,7 @@ void main() { expect(editableText.cursorOpacityAnimates, false); }); - testWidgets( + testWidgetsWithLeakTracking( 'takes available space horizontally and takes intrinsic space vertically', (WidgetTester tester) async { await tester.pumpWidget( @@ -619,7 +629,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'uses DefaultSelectionStyle for selection and cursor colors if provided', (WidgetTester tester) async { const Color selectionColor = Colors.black; @@ -645,11 +655,12 @@ void main() { }, ); - testWidgets('Text field drops selection color when losing focus', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Text field drops selection color when losing focus', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/103341. final Key key1 = UniqueKey(); final Key key2 = UniqueKey(); final TextEditingController controller1 = TextEditingController(); + addTearDown(controller1.dispose); const Color selectionColor = Colors.orange; const Color cursorColor = Colors.red; @@ -702,7 +713,7 @@ void main() { expect(state2.widget.selectionColor, selectionColor); }); - testWidgets( + testWidgetsWithLeakTracking( 'multi-lined text fields are intrinsically taller no-strut', (WidgetTester tester) async { await tester.pumpWidget( @@ -726,7 +737,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'multi-lined text fields are intrinsically taller', (WidgetTester tester) async { await tester.pumpWidget( @@ -747,7 +758,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'strut height override', (WidgetTester tester) async { await tester.pumpWidget( @@ -776,7 +787,7 @@ void main() { skip: isBrowser, // https://github.com/flutter/flutter/issues/32243 ); - testWidgets( + testWidgetsWithLeakTracking( 'strut forces field taller', (WidgetTester tester) async { await tester.pumpWidget( @@ -806,7 +817,7 @@ void main() { skip: isBrowser, // https://github.com/flutter/flutter/issues/32243 ); - testWidgets( + testWidgetsWithLeakTracking( 'default text field has a border', (WidgetTester tester) async { await tester.pumpWidget( @@ -861,7 +872,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'decoration can be overridden', (WidgetTester tester) async { await tester.pumpWidget( @@ -884,14 +895,16 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'text entries are padded by default', (WidgetTester tester) async { + final TextEditingController controller = TextEditingController(text: 'initial'); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( child: CupertinoTextField( - controller: TextEditingController(text: 'initial'), + controller: controller, ), ), ), @@ -904,7 +917,7 @@ void main() { }, ); - testWidgets('iOS cursor has offset', (WidgetTester tester) async { + testWidgetsWithLeakTracking('iOS cursor has offset', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoTextField(), @@ -915,7 +928,7 @@ void main() { expect(editableText.cursorOffset, const Offset(-2.0 / 3.0, 0)); }); - testWidgets('Cursor radius is 2.0', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Cursor radius is 2.0', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoTextField(), @@ -928,7 +941,7 @@ void main() { expect(renderEditable.cursorRadius, const Radius.circular(2.0)); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets('Cupertino cursor android golden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Cupertino cursor android golden', (WidgetTester tester) async { final Widget widget = CupertinoApp( home: Center( child: RepaintBoundary( @@ -955,7 +968,7 @@ void main() { ); }); - testWidgets('Cupertino cursor golden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Cupertino cursor golden', (WidgetTester tester) async { final Widget widget = CupertinoApp( home: Center( child: RepaintBoundary( @@ -984,10 +997,11 @@ void main() { ); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets( + testWidgetsWithLeakTracking( 'can control text content via controller', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -1011,7 +1025,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'placeholder respects textAlign', (WidgetTester tester) async { await tester.pumpWidget( @@ -1036,7 +1050,7 @@ void main() { }, ); - testWidgets('placeholder dark mode', (WidgetTester tester) async { + testWidgetsWithLeakTracking('placeholder dark mode', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( theme: CupertinoThemeData(brightness: Brightness.dark), @@ -1053,7 +1067,7 @@ void main() { expect(placeholder.style!.color!.value, CupertinoColors.placeholderText.darkColor.value); }); - testWidgets( + testWidgetsWithLeakTracking( 'placeholders are lightly colored and disappears once typing starts', (WidgetTester tester) async { await tester.pumpWidget( @@ -1076,7 +1090,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( "placeholderStyle modifies placeholder's style and doesn't affect text's style", (WidgetTester tester) async { await tester.pumpWidget( @@ -1110,17 +1124,20 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'prefix widget is in front of the text', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); + final TextEditingController controller = TextEditingController(text: 'input'); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( child: CupertinoTextField( focusNode: focusNode, prefix: const Icon(CupertinoIcons.add), - controller: TextEditingController(text: 'input'), + controller: controller, ), ), ), @@ -1140,7 +1157,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'prefix widget respects visibility mode', (WidgetTester tester) async { await tester.pumpWidget( @@ -1177,10 +1194,11 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'suffix widget is after the text', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -1206,7 +1224,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'suffix widget respects visibility mode', (WidgetTester tester) async { await tester.pumpWidget( @@ -1230,7 +1248,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'can customize padding', (WidgetTester tester) async { await tester.pumpWidget( @@ -1250,7 +1268,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'padding is in between prefix and suffix no-strut', (WidgetTester tester) async { await tester.pumpWidget( @@ -1308,7 +1326,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'padding is in between prefix and suffix', (WidgetTester tester) async { await tester.pumpWidget( @@ -1364,10 +1382,11 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'clear button shows with right visibility mode', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -1435,10 +1454,11 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'clear button removes text', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -1464,11 +1484,12 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'tapping clear button also calls onChanged when text not empty', (WidgetTester tester) async { String value = 'text entry'; final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -1494,10 +1515,11 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'clear button yields precedence to suffix', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -1533,7 +1555,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'font style controls intrinsic height no-strut', (WidgetTester tester) async { await tester.pumpWidget( @@ -1572,7 +1594,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'font style controls intrinsic height', (WidgetTester tester) async { await tester.pumpWidget( @@ -1608,7 +1630,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'RTL puts attachments to the right places', (WidgetTester tester) async { await tester.pumpWidget( @@ -1638,7 +1660,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'text fields with no max lines can grow no-strut', (WidgetTester tester) async { await tester.pumpWidget( @@ -1667,7 +1689,7 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'text fields with no max lines can grow', (WidgetTester tester) async { await tester.pumpWidget( @@ -1695,8 +1717,9 @@ void main() { }, ); - testWidgets('cannot enter new lines onto single line TextField', (WidgetTester tester) async { + testWidgetsWithLeakTracking('cannot enter new lines onto single line TextField', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -1713,10 +1736,11 @@ void main() { expect(controller.text, 'abcdef'); }); - testWidgets('toolbar colors change with theme brightness, but nothing else', (WidgetTester tester) async { + testWidgetsWithLeakTracking('toolbar colors change with theme brightness, but nothing else', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: "j'aime la poutine", ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -1775,10 +1799,11 @@ void main() { expect(text.style!.fontWeight, FontWeight.w400); }, skip: isContextMenuProvidedByPlatform); // [intended] only applies to platforms where we supply the context menu. - testWidgets('text field toolbar options correctly changes options on Apple Platforms', (WidgetTester tester) async { + testWidgetsWithLeakTracking('text field toolbar options correctly changes options on Apple Platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Column( @@ -1825,10 +1850,11 @@ void main() { skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu. ); - testWidgets('text field toolbar options correctly changes options on non-Apple Platforms', (WidgetTester tester) async { + testWidgetsWithLeakTracking('text field toolbar options correctly changes options on non-Apple Platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Column( @@ -1880,8 +1906,9 @@ void main() { skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu. ); - testWidgets('Read only text field', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Read only text field', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(text: 'readonly'); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -1917,7 +1944,7 @@ void main() { expect(find.text('Cut'), findsNothing); }, skip: isContextMenuProvidedByPlatform); // [intended] only applies to platforms where we supply the context menu. - testWidgets('copy paste', (WidgetTester tester) async { + testWidgetsWithLeakTracking('copy paste', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: Column( @@ -1970,12 +1997,13 @@ void main() { expect(Visibility.of(placeholder2Element), false); }, skip: isContextMenuProvidedByPlatform); // [intended] only applies to platforms where we supply the context menu. - testWidgets( + testWidgetsWithLeakTracking( 'tap moves cursor to the edge of the word it tapped on', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -2001,12 +2029,13 @@ void main() { expect(find.byType(CupertinoButton), findsNothing); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS })); - testWidgets( + testWidgetsWithLeakTracking( 'slow double tap does not trigger double tap', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); // On iOS/iPadOS, during a tap we select the edge of the word closest to the tap. // On macOS, we select the precise position of the tap. final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS; @@ -2035,12 +2064,13 @@ void main() { expect(find.byType(CupertinoButton), isContextMenuProvidedByPlatform ? findsNothing : isTargetPlatformIOS ? findsNWidgets(2) : findsNothing); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets( + testWidgetsWithLeakTracking( 'Tapping on a collapsed selection toggles the toolbar', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neigse Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges', ); + addTearDown(controller.dispose); // On iOS/iPadOS, during a tap we select the edge of the word closest to the tap. await tester.pumpWidget( CupertinoApp( @@ -2120,12 +2150,13 @@ void main() { variant: const TargetPlatformVariant({ TargetPlatform.iOS }), ); - testWidgets( + testWidgetsWithLeakTracking( 'Tapping on a non-collapsed selection toggles the toolbar and retains the selection', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); // On iOS/iPadOS, during a tap we select the edge of the word closest to the tap. await tester.pumpWidget( CupertinoApp( @@ -2194,12 +2225,13 @@ void main() { variant: const TargetPlatformVariant({ TargetPlatform.iOS }), ); - testWidgets( + testWidgetsWithLeakTracking( 'double tap selects word for non-Apple platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -2249,12 +2281,13 @@ void main() { variant: TargetPlatformVariant.all(excluding: { TargetPlatform.iOS, TargetPlatform.macOS}), ); - testWidgets( + testWidgetsWithLeakTracking( 'double tap selects word for Apple platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -2308,12 +2341,13 @@ void main() { variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS }), ); - testWidgets( + testWidgetsWithLeakTracking( 'double tap does not select word on read-only obscured field', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -2346,10 +2380,11 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'Can double click + drag with a mouse to select word by word', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -2395,10 +2430,11 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'Can double tap + drag to select word by word', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -2449,10 +2485,13 @@ void main() { await gesture.up(); await tester.pump(); expect(find.byType(CupertinoButton), isContextMenuProvidedByPlatform ? findsNothing : findsNWidgets(4)); + + // Skip the magnifier hide animation, so it can release resources. + await tester.pump(const Duration(milliseconds: 150)); }, ); - testWidgets('Readonly text field does not have tap action', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Readonly text field does not have tap action', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( @@ -2471,12 +2510,13 @@ void main() { semantics.dispose(); }); - testWidgets( + testWidgetsWithLeakTracking( 'double tap selects word and first tap of double tap moves cursor', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); // On iOS/iPadOS, during a tap we select the edge of the word closest to the tap. // On macOS, we select the precise position of the tap. final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS; @@ -2516,12 +2556,13 @@ void main() { expect(find.byType(CupertinoButton), isContextMenuProvidedByPlatform ? findsNothing : (isTargetPlatformIOS ? findsNWidgets(6) : findsNWidgets(3))); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets( + testWidgetsWithLeakTracking( 'double tap hold selects word', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -2575,12 +2616,13 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'tap after a double tap select is not affected', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); // On iOS/iPadOS, during a tap we select the edge of the word closest to the tap. // On macOS, we select the precise position of the tap. final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS; @@ -2620,10 +2662,11 @@ void main() { expect(find.byType(CupertinoButton), findsNothing); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets('double tapping a space selects the previous word on iOS', (WidgetTester tester) async { + testWidgetsWithLeakTracking('double tapping a space selects the previous word on iOS', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: ' blah blah \n blah', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -2689,10 +2732,11 @@ void main() { expect(controller.value.selection.extentOffset, 14); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS })); - testWidgets('double tapping a space selects the space on Mac', (WidgetTester tester) async { + testWidgetsWithLeakTracking('double tapping a space selects the space on Mac', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: ' blah blah', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -2743,10 +2787,11 @@ void main() { expect(controller.value.selection.extentOffset, 1); }, variant: const TargetPlatformVariant({ TargetPlatform.macOS })); - testWidgets('double clicking a space selects the space on Mac', (WidgetTester tester) async { + testWidgetsWithLeakTracking('double clicking a space selects the space on Mac', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: ' blah blah', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -2810,12 +2855,13 @@ void main() { expect(controller.value.selection.extentOffset, 1); }, variant: const TargetPlatformVariant({ TargetPlatform.macOS })); - testWidgets( + testWidgetsWithLeakTracking( 'An obscured CupertinoTextField is not selectable when disabled', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -2858,12 +2904,13 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'A read-only obscured CupertinoTextField is not selectable', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -2906,12 +2953,13 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'An obscured CupertinoTextField is selectable by default', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -2953,10 +3001,11 @@ void main() { }, ); - testWidgets('An obscured TextField has correct default context menu', (WidgetTester tester) async { + testWidgetsWithLeakTracking('An obscured TextField has correct default context menu', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -2997,12 +3046,13 @@ void main() { expect(find.text('Cut'), findsNothing); }, skip: isContextMenuProvidedByPlatform); // [intended] only applies to platforms where we supply the context menu. - testWidgets( + testWidgetsWithLeakTracking( 'long press selects the word at the long press position and shows toolbar on non-Apple platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -3030,12 +3080,13 @@ void main() { variant: TargetPlatformVariant.all(excluding: { TargetPlatform.iOS, TargetPlatform.macOS }), ); - testWidgets( + testWidgetsWithLeakTracking( 'long press moves cursor to the exact long press position and shows toolbar on Apple platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -3074,12 +3125,13 @@ void main() { variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS }), ); - testWidgets( + testWidgetsWithLeakTracking( 'long press tap cannot initiate a double tap', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -3124,12 +3176,13 @@ void main() { expect(find.byType(CupertinoButton), findsNothing); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets( + testWidgetsWithLeakTracking( 'long press drag selects word by word and shows toolbar on lift on non-Apple platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -3188,12 +3241,13 @@ void main() { variant: TargetPlatformVariant.all(excluding: { TargetPlatform.iOS, TargetPlatform.macOS }), ); - testWidgets( + testWidgetsWithLeakTracking( 'long press drag on a focused TextField moves the cursor under the drag and shows toolbar on lift on Apple platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -3263,10 +3317,11 @@ void main() { variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS }), ); - testWidgets('long press drag can edge scroll on non-Apple platforms', (WidgetTester tester) async { + testWidgetsWithLeakTracking('long press drag can edge scroll on non-Apple platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -3349,10 +3404,11 @@ void main() { expect(firstCharEndpoint[0].point.dx, moreOrLessEquals(-310.30, epsilon: 1)); }, variant: TargetPlatformVariant.all(excluding: { TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets('long press drag can edge scroll on Apple platforms', (WidgetTester tester) async { + testWidgetsWithLeakTracking('long press drag can edge scroll on Apple platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -3450,12 +3506,13 @@ void main() { expect(firstCharEndpoint[0].point.dx, moreOrLessEquals(-310.20, epsilon: 0.25)); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets( + testWidgetsWithLeakTracking( 'long tap after a double tap select is not affected', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); // On iOS/iPadOS, during a tap we select the edge of the word closest to the tap. // On macOS, we select the precise position of the tap. final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS; @@ -3502,12 +3559,13 @@ void main() { expect(find.byType(CupertinoButton), findsNWidgets(toolbarButtons)); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets( + testWidgetsWithLeakTracking( 'double tap after a long tap is not affected', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); // On iOS/iPadOS, during a tap we select the edge of the word closest to the tap. // On macOS, we select the precise position of the tap. final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS; @@ -3561,12 +3619,13 @@ void main() { expect(find.byType(CupertinoButton), isContextMenuProvidedByPlatform ? findsNothing : (isTargetPlatformIOS ? findsNWidgets(6) : findsNWidgets(3))); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets( + testWidgetsWithLeakTracking( 'double tap chains work', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -3640,11 +3699,12 @@ void main() { 'all good people\n' // 22 + 16 => 38 'to come to the aid\n' // 38 + 19 => 57 'of their country.'; // 57 + 17 => 74 - testWidgets( + testWidgetsWithLeakTracking( 'Can triple tap to select a paragraph on mobile platforms when tapping at a word edge', (WidgetTester tester) async { // TODO(Renzo-Olivares): Enable, currently broken because selection overlay blocks the TextSelectionGestureDetector. final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); final bool isTargetPlatformApple = defaultTargetPlatform == TargetPlatform.iOS; await tester.pumpWidget( @@ -3700,10 +3760,11 @@ void main() { skip: true, // https://github.com/flutter/flutter/issues/123415 ); - testWidgets( + testWidgetsWithLeakTracking( 'Can triple tap to select a paragraph on mobile platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); final bool isTargetPlatformApple = defaultTargetPlatform == TargetPlatform.iOS; await tester.pumpWidget( @@ -3758,11 +3819,12 @@ void main() { variant: TargetPlatformVariant.mobile(), ); - testWidgets( + testWidgetsWithLeakTracking( 'Triple click at the beginning of a line should not select the previous paragraph', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/132126 final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -3815,11 +3877,12 @@ void main() { variant: TargetPlatformVariant.all(excluding: { TargetPlatform.linux }), ); - testWidgets( + testWidgetsWithLeakTracking( 'Triple click at the end of text should select the previous paragraph', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/132126. final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -3873,12 +3936,13 @@ void main() { variant: TargetPlatformVariant.all(excluding: { TargetPlatform.linux }), ); - testWidgets( + testWidgetsWithLeakTracking( 'triple tap chains work on Non-Apple mobile platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -3963,12 +4027,13 @@ void main() { variant: const TargetPlatformVariant({ TargetPlatform.android, TargetPlatform.fuchsia }), ); - testWidgets( + testWidgetsWithLeakTracking( 'triple tap chains work on Apple platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure\nThe fox jumped over the fence.', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -4063,12 +4128,13 @@ void main() { variant: const TargetPlatformVariant({ TargetPlatform.iOS }), ); - testWidgets( + testWidgetsWithLeakTracking( 'triple click chains work', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: testValueA, ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -4180,12 +4246,13 @@ void main() { variant: TargetPlatformVariant.desktop(), ); - testWidgets( + testWidgetsWithLeakTracking( 'triple click after a click on desktop platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: testValueA, ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -4244,12 +4311,13 @@ void main() { variant: TargetPlatformVariant.desktop(), ); - testWidgets( + testWidgetsWithLeakTracking( 'Can triple tap to select all on a single-line textfield on mobile platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: testValueB, ); + addTearDown(controller.dispose); final bool isTargetPlatformApple = defaultTargetPlatform == TargetPlatform.iOS; await tester.pumpWidget( @@ -4299,12 +4367,13 @@ void main() { variant: TargetPlatformVariant.mobile(), ); - testWidgets( + testWidgetsWithLeakTracking( 'Can triple click to select all on a single-line textfield on desktop platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: testValueA, ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -4355,10 +4424,11 @@ void main() { variant: TargetPlatformVariant.desktop(), ); - testWidgets( + testWidgetsWithLeakTracking( 'Can triple click to select a line on Linux', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -4416,10 +4486,11 @@ void main() { variant: TargetPlatformVariant.only(TargetPlatform.linux), ); - testWidgets( + testWidgetsWithLeakTracking( 'Can triple click to select a paragraph', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -4477,10 +4548,11 @@ void main() { variant: TargetPlatformVariant.all(excluding: { TargetPlatform.linux }), ); - testWidgets( + testWidgetsWithLeakTracking( 'Can triple click + drag to select line by line on Linux', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -4579,10 +4651,11 @@ void main() { variant: TargetPlatformVariant.only(TargetPlatform.linux), ); - testWidgets( + testWidgetsWithLeakTracking( 'Can triple click + drag to select paragraph by paragraph', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -4681,12 +4754,13 @@ void main() { variant: TargetPlatformVariant.all(excluding: { TargetPlatform.linux }), ); - testWidgets( + testWidgetsWithLeakTracking( 'Going past triple click retains the selection on Apple platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: testValueA, ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -4768,12 +4842,13 @@ void main() { variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS }), ); - testWidgets( + testWidgetsWithLeakTracking( 'Tap count resets when going past a triple tap on Android, Fuchsia, and Linux', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: testValueA, ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -4882,12 +4957,13 @@ void main() { variant: const TargetPlatformVariant({ TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.linux }), ); - testWidgets( + testWidgetsWithLeakTracking( 'Double click and triple click alternate on Windows', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: testValueA, ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -5000,10 +5076,11 @@ void main() { ); }); - testWidgets('force press selects word', (WidgetTester tester) async { + testWidgetsWithLeakTracking('force press selects word', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -5055,10 +5132,11 @@ void main() { expect(find.byType(CupertinoButton), matchToolbarButtons); }); - testWidgets('force press on unsupported devices falls back to tap', (WidgetTester tester) async { + testWidgetsWithLeakTracking('force press on unsupported devices falls back to tap', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); // On iOS/iPadOS, during a tap we select the edge of the word closest to the tap. // On macOS, we select the precise position of the tap. final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS; @@ -5098,10 +5176,11 @@ void main() { expect(find.byType(CupertinoButton), findsNothing); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets('Cannot drag one handle past the other', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Cannot drag one handle past the other', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'abc def ghi', ); + addTearDown(controller.dispose); // On iOS/iPadOS, during a tap we select the edge of the word closest to the tap. // On macOS, we select the precise position of the tap. final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS; @@ -5165,11 +5244,12 @@ void main() { expect(controller.selection.extentOffset, 5); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS })); - testWidgets('Dragging between multiple lines keeps the contact point at the same place on the handle on Android', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dragging between multiple lines keeps the contact point at the same place on the handle on Android', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( // 11 first line, 19 second line, 17 third line = length 49 text: 'a big house\njumped over a mouse\nOne more line yay', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -5363,11 +5443,12 @@ void main() { variant: const TargetPlatformVariant({ TargetPlatform.android }), ); - testWidgets('Dragging between multiple lines keeps the contact point at the same place on the handle on iOS', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dragging between multiple lines keeps the contact point at the same place on the handle on iOS', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( // 11 first line, 19 second line, 17 third line = length 49 text: 'a big house\njumped over a mouse\nOne more line yay', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -5552,8 +5633,9 @@ void main() { variant: const TargetPlatformVariant({ TargetPlatform.iOS }), ); - testWidgets('Selection updates on tap down (Desktop platforms)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Selection updates on tap down (Desktop platforms)', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -5593,8 +5675,9 @@ void main() { variant: TargetPlatformVariant.desktop(), ); - testWidgets('Selection updates on tap up (Mobile platforms)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Selection updates on tap up (Mobile platforms)', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); final bool isTargetPlatformApple = defaultTargetPlatform == TargetPlatform.iOS; await tester.pumpWidget( @@ -5649,8 +5732,9 @@ void main() { variant: TargetPlatformVariant.mobile(), ); - testWidgets('Can select text by dragging with a mouse', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can select text by dragging with a mouse', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -5684,8 +5768,9 @@ void main() { expect(controller.selection.extentOffset, testValue.indexOf('g')); }); - testWidgets('Cursor should not move on a quick touch drag when touch does not begin on previous selection (iOS)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Cursor should not move on a quick touch drag when touch does not begin on previous selection (iOS)', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -5729,8 +5814,9 @@ void main() { variant: const TargetPlatformVariant({ TargetPlatform.iOS }), ); - testWidgets('Can move cursor when dragging, when tap is on collapsed selection (iOS)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can move cursor when dragging, when tap is on collapsed selection (iOS)', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -5772,12 +5858,19 @@ void main() { expect(controller.selection.isCollapsed, true); expect(controller.selection.baseOffset, testValue.indexOf('i')); + + // End gesture and skip the magnifier hide animation, so it can release + // resources. + await gesture.up(); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 150)); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS }), ); - testWidgets('Can move cursor when dragging, when tap is on collapsed selection (iOS) - multiline', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can move cursor when dragging, when tap is on collapsed selection (iOS) - multiline', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -5820,14 +5913,21 @@ void main() { expect(controller.selection.isCollapsed, true); expect(controller.selection.baseOffset, testValue.indexOf('i')); + + // End gesture and skip the magnifier hide animation, so it can release + // resources. + await gesture.up(); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 150)); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS }), ); - testWidgets('Can move cursor when dragging, when tap is on collapsed selection (iOS) - ListView', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can move cursor when dragging, when tap is on collapsed selection (iOS) - ListView', (WidgetTester tester) async { // This is a regression test for // https://github.com/flutter/flutter/issues/122519 final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -5900,8 +6000,9 @@ void main() { variant: const TargetPlatformVariant({ TargetPlatform.iOS }), ); - testWidgets('Can move cursor when dragging (Android)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can move cursor when dragging (Android)', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -5940,14 +6041,21 @@ void main() { expect(controller.selection.isCollapsed, true); expect(controller.selection.baseOffset, testValue.indexOf('g')); + + // End gesture and skip the magnifier hide animation, so it can release + // resources. + await gesture.up(); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 150)); }, variant: const TargetPlatformVariant({ TargetPlatform.android, TargetPlatform.fuchsia }), ); - testWidgets('Continuous dragging does not cause flickering', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Continuous dragging does not cause flickering', (WidgetTester tester) async { int selectionChangedCount = 0; const String testValue = 'abc def ghi'; final TextEditingController controller = TextEditingController(text: testValue); + addTearDown(controller.dispose); controller.addListener(() { selectionChangedCount++; @@ -5996,10 +6104,11 @@ void main() { expect(controller.selection.extentOffset, 9); }); - testWidgets('Tap does not show handles nor toolbar', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Tap does not show handles nor toolbar', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'abc def ghi', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -6018,10 +6127,11 @@ void main() { expect(editableText.selectionOverlay!.toolbarIsVisible, isFalse); }); - testWidgets('Long press shows toolbar but not handles', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Long press shows toolbar but not handles', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'abc def ghi', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -6042,12 +6152,13 @@ void main() { expect(editableText.selectionOverlay!.toolbarIsVisible, isContextMenuProvidedByPlatform ? isFalse : isTrue); }); - testWidgets( + testWidgetsWithLeakTracking( 'Double tap shows handles and toolbar if selection is not collapsed', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'abc def ghi', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -6071,12 +6182,13 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'Double tap shows toolbar but not handles if selection is collapsed', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'abc def ghi', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -6100,12 +6212,13 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'Mouse long press does not show handles nor toolbar', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'abc def ghi', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -6131,12 +6244,13 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'Mouse double tap does not show handles nor toolbar', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'abc def ghi', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -6182,7 +6296,7 @@ void main() { }, ); - testWidgets('onTap is called upon tap', (WidgetTester tester) async { + testWidgetsWithLeakTracking('onTap is called upon tap', (WidgetTester tester) async { int tapCount = 0; await tester.pumpWidget( CupertinoApp( @@ -6211,7 +6325,7 @@ void main() { expect(tapCount, 2); }); - testWidgets( + testWidgetsWithLeakTracking( 'onTap does not work when the text field is disabled', (WidgetTester tester) async { int tapCount = 0; @@ -6268,8 +6382,9 @@ void main() { }, ); - testWidgets('Focus test when the text field is disabled', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Focus test when the text field is disabled', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -6305,7 +6420,7 @@ void main() { expect(focusNode.hasFocus, false); }); - testWidgets( + testWidgetsWithLeakTracking( 'text field respects theme', (WidgetTester tester) async { await tester.pumpWidget( @@ -6343,13 +6458,14 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'Check the toolbar appears below the TextField when there is not enough space above the TextField to show it', (WidgetTester tester) async { // This is a regression test for // https://github.com/flutter/flutter/issues/29808 const String testValue = 'abc def ghi'; final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -6414,7 +6530,7 @@ void main() { skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu. ); - testWidgets('text field respects keyboardAppearance from theme', (WidgetTester tester) async { + testWidgetsWithLeakTracking('text field respects keyboardAppearance from theme', (WidgetTester tester) async { final List log = []; tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async { log.add(methodCall); @@ -6438,7 +6554,7 @@ void main() { expect(((setClient.arguments as List).last as Map)['keyboardAppearance'], 'Brightness.dark'); }); - testWidgets('text field can override keyboardAppearance from theme', (WidgetTester tester) async { + testWidgetsWithLeakTracking('text field can override keyboardAppearance from theme', (WidgetTester tester) async { final List log = []; tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async { log.add(methodCall); @@ -6464,7 +6580,7 @@ void main() { expect(((setClient.arguments as List).last as Map)['keyboardAppearance'], 'Brightness.light'); }); - testWidgets('cursorColor respects theme', (WidgetTester tester) async { + testWidgetsWithLeakTracking('cursorColor respects theme', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoTextField(), @@ -6506,7 +6622,7 @@ void main() { expect(renderEditable.cursorColor, const Color(0xFFF44336)); }); - testWidgets('cursor can override color from theme', (WidgetTester tester) async { + testWidgetsWithLeakTracking('cursor can override color from theme', (WidgetTester tester) async { const CupertinoDynamicColor cursorColor = CupertinoDynamicColor.withBrightness( color: Color(0x12345678), darkColor: Color(0x87654321), @@ -6541,9 +6657,10 @@ void main() { expect(editableText.cursorColor.value, 0x87654321); }); - testWidgets('shows selection handles', (WidgetTester tester) async { + testWidgetsWithLeakTracking('shows selection handles', (WidgetTester tester) async { const String testText = 'lorem ipsum'; final TextEditingController controller = TextEditingController(text: testText); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -6573,9 +6690,11 @@ void main() { expect(right.opacity.value, equals(1.0)); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets('when CupertinoTextField would be blocked by keyboard, it is shown with enough space for the selection handle', (WidgetTester tester) async { + testWidgetsWithLeakTracking('when CupertinoTextField would be blocked by keyboard, it is shown with enough space for the selection handle', (WidgetTester tester) async { final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget(CupertinoApp( theme: const CupertinoThemeData(), @@ -6601,7 +6720,9 @@ void main() { expect(scrollController.offset, 27.0); }); - testWidgets('disabled state golden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('disabled state golden', (WidgetTester tester) async { + final TextEditingController controller = TextEditingController(text: 'lorem'); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: DecoratedBox( @@ -6613,7 +6734,7 @@ void main() { child: RepaintBoundary( key: const ValueKey(1), child: CupertinoTextField( - controller: TextEditingController(text: 'lorem'), + controller: controller, enabled: false, ), ), @@ -6629,13 +6750,16 @@ void main() { ); }); - testWidgets( + testWidgetsWithLeakTracking( 'Can drag the left handle while the right handle remains off-screen', (WidgetTester tester) async { // Text is longer than textfield width. const String testValue = 'aaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbb'; final TextEditingController controller = TextEditingController(text: testValue); + addTearDown(controller.dispose); final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); + await tester.pumpWidget( CupertinoApp( @@ -6712,13 +6836,15 @@ void main() { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'Can drag the right handle while the left handle remains off-screen', (WidgetTester tester) async { // Text is longer than textfield width. const String testValue = 'aaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbb'; final TextEditingController controller = TextEditingController(text: testValue); + addTearDown(controller.dispose); final ScrollController scrollController = ScrollController(); + addTearDown(scrollController.dispose); await tester.pumpWidget( CupertinoApp( @@ -6785,7 +6911,7 @@ void main() { ); group('Text selection toolbar', () { - testWidgets('Collapsed selection works', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Collapsed selection works', (WidgetTester tester) async { tester.view.physicalSize = const Size(400, 400); tester.view.devicePixelRatio = 1; addTearDown(tester.view.reset); @@ -6858,6 +6984,7 @@ void main() { // Top Right collapsed selection. The toolbar should flip vertically, and // the arrow should not point exactly to the caret because the caret is // too close to the right. + controller.dispose(); controller = TextEditingController(text: List.filled(200, 'a').join()); await tester.pumpWidget( CupertinoApp( @@ -6918,7 +7045,9 @@ void main() { // Normal centered collapsed selection. The toolbar arrow should point down, and // it should point exactly to the caret. + controller.dispose(); controller = TextEditingController(text: List.filled(200, 'a').join()); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( debugShowCheckedModeBanner: false, @@ -6971,7 +7100,7 @@ void main() { ); }); - testWidgets('selecting multiple words works', (WidgetTester tester) async { + testWidgetsWithLeakTracking('selecting multiple words works', (WidgetTester tester) async { tester.view.physicalSize = const Size(400, 400); tester.view.devicePixelRatio = 1; addTearDown(tester.view.reset); @@ -6983,6 +7112,7 @@ void main() { // Normal multiword collapsed selection. The toolbar arrow should point down, and // it should point exactly to the caret. controller = TextEditingController(text: List.filled(20, 'a').join(' ')); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( debugShowCheckedModeBanner: false, @@ -7040,7 +7170,7 @@ void main() { ); }); - testWidgets('selecting multiline works', (WidgetTester tester) async { + testWidgetsWithLeakTracking('selecting multiline works', (WidgetTester tester) async { tester.view.physicalSize = const Size(400, 400); tester.view.devicePixelRatio = 1; addTearDown(tester.view.reset); @@ -7052,6 +7182,7 @@ void main() { // Normal multiline collapsed selection. The toolbar arrow should point down, and // it should point exactly to the horizontal center of the text field. controller = TextEditingController(text: List.filled(20, 'a a ').join('\n')); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( debugShowCheckedModeBanner: false, @@ -7115,11 +7246,12 @@ void main() { // This is a regression test for // https://github.com/flutter/flutter/issues/37046. - testWidgets('No exceptions when showing selection menu inside of nested Navigators', (WidgetTester tester) async { + testWidgetsWithLeakTracking('No exceptions when showing selection menu inside of nested Navigators', (WidgetTester tester) async { const String testValue = '123456'; final TextEditingController controller = TextEditingController( text: testValue, ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: CupertinoPageScaffold( @@ -7161,10 +7293,11 @@ void main() { expect(tester.takeException(), null); }); - testWidgets('Drag selection hides the selection menu', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Drag selection hides the selection menu', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'blah1 blah2', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -7211,8 +7344,9 @@ void main() { group('textAlignVertical position', () { group('simple case', () { - testWidgets('align top (default)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('align top (default)', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); const Size size = Size(200.0, 200.0); await tester.pumpWidget( CupertinoApp( @@ -7257,8 +7391,9 @@ void main() { expect(tester.getTopLeft(find.byType(EditableText)).dy, moreOrLessEquals(207.0, epsilon: .0001)); }); - testWidgets('align center', (WidgetTester tester) async { + testWidgetsWithLeakTracking('align center', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); const Size size = Size(200.0, 200.0); await tester.pumpWidget( CupertinoApp( @@ -7304,8 +7439,9 @@ void main() { expect(tester.getTopLeft(find.byType(EditableText)).dy, moreOrLessEquals(291.5, epsilon: .0001)); }); - testWidgets('align bottom', (WidgetTester tester) async { + testWidgetsWithLeakTracking('align bottom', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); const Size size = Size(200.0, 200.0); await tester.pumpWidget( CupertinoApp( @@ -7351,8 +7487,9 @@ void main() { expect(tester.getTopLeft(find.byType(EditableText)).dy, moreOrLessEquals(376.0, epsilon: .0001)); }); - testWidgets('align as a double', (WidgetTester tester) async { + testWidgetsWithLeakTracking('align as a double', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); const Size size = Size(200.0, 200.0); await tester.pumpWidget( CupertinoApp( @@ -7400,8 +7537,9 @@ void main() { }); group('tall prefix', () { - testWidgets('align center (default when prefix)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('align center (default when prefix)', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); const Size size = Size(200.0, 200.0); await tester.pumpWidget( CupertinoApp( @@ -7451,8 +7589,9 @@ void main() { expect(tester.getTopLeft(find.byType(EditableText)).dy, moreOrLessEquals(291.5, epsilon: .0001)); }); - testWidgets('align top', (WidgetTester tester) async { + testWidgetsWithLeakTracking('align top', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); const Size size = Size(200.0, 200.0); await tester.pumpWidget( CupertinoApp( @@ -7504,8 +7643,9 @@ void main() { expect(tester.getTopLeft(find.byType(EditableText)).dy, moreOrLessEquals(241.5, epsilon: .0001)); }); - testWidgets('align bottom', (WidgetTester tester) async { + testWidgetsWithLeakTracking('align bottom', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); const Size size = Size(200.0, 200.0); await tester.pumpWidget( CupertinoApp( @@ -7557,8 +7697,9 @@ void main() { expect(tester.getTopLeft(find.byType(EditableText)).dy, moreOrLessEquals(341.5, epsilon: .0001)); }); - testWidgets('align as a double', (WidgetTester tester) async { + testWidgetsWithLeakTracking('align as a double', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); const Size size = Size(200.0, 200.0); await tester.pumpWidget( CupertinoApp( @@ -7610,7 +7751,7 @@ void main() { }); }); - testWidgets( + testWidgetsWithLeakTracking( 'Long press on an autofocused field shows the selection menu', (WidgetTester tester) async { await tester.pumpWidget( @@ -7637,7 +7778,7 @@ void main() { ); }); - testWidgets("Arrow keys don't move input focus", (WidgetTester tester) async { + testWidgetsWithLeakTracking("Arrow keys don't move input focus", (WidgetTester tester) async { final TextEditingController controller1 = TextEditingController(); final TextEditingController controller2 = TextEditingController(); final TextEditingController controller3 = TextEditingController(); @@ -7648,6 +7789,16 @@ void main() { final FocusNode focusNode3 = FocusNode(debugLabel: 'Field 3'); final FocusNode focusNode4 = FocusNode(debugLabel: 'Field 4'); final FocusNode focusNode5 = FocusNode(debugLabel: 'Field 5'); + addTearDown(focusNode1.dispose); + addTearDown(focusNode2.dispose); + addTearDown(focusNode3.dispose); + addTearDown(focusNode4.dispose); + addTearDown(focusNode5.dispose); + addTearDown(controller1.dispose); + addTearDown(controller2.dispose); + addTearDown(controller3.dispose); + addTearDown(controller4.dispose); + addTearDown(controller5.dispose); // Lay out text fields in a "+" formation, and focus the center one. await tester.pumpWidget(CupertinoApp( @@ -7724,7 +7875,7 @@ void main() { expect(focusNode3.hasPrimaryFocus, isTrue); }, variant: KeySimulatorTransitModeVariant.all()); - testWidgets('Scrolling shortcuts are disabled in text fields', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Scrolling shortcuts are disabled in text fields', (WidgetTester tester) async { bool scrollInvoked = false; await tester.pumpWidget( CupertinoApp( @@ -7758,7 +7909,7 @@ void main() { expect(scrollInvoked, isFalse); }, variant: KeySimulatorTransitModeVariant.all()); - testWidgets('Cupertino text field semantics', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Cupertino text field semantics', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: Center( @@ -7786,7 +7937,7 @@ void main() { ); }); - testWidgets('Disabled Cupertino text field semantics', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Disabled Cupertino text field semantics', (WidgetTester tester) async { await tester.pumpWidget( CupertinoApp( home: Center( @@ -7815,10 +7966,11 @@ void main() { ); }); - testWidgets('text selection style 1', (WidgetTester tester) async { + testWidgetsWithLeakTracking('text selection style 1', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure\nhi\nwassssup!', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -7869,10 +8021,11 @@ void main() { skip: kIsWeb, // [intended] the web has its own Select All. ); - testWidgets('text selection style 2', (WidgetTester tester) async { + testWidgetsWithLeakTracking('text selection style 2', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure\nhi\nwassssup!', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -7922,7 +8075,7 @@ void main() { skip: kIsWeb, // [intended] the web has its own Select All. ); - testWidgets('textSelectionControls is passed to EditableText', (WidgetTester tester) async { + testWidgetsWithLeakTracking('textSelectionControls is passed to EditableText', (WidgetTester tester) async { final MockTextSelectionControls selectionControl = MockTextSelectionControls(); await tester.pumpWidget( CupertinoApp( @@ -7938,7 +8091,7 @@ void main() { expect(widget.selectionControls, equals(selectionControl)); }); - testWidgets('Do not add LengthLimiting formatter to the user supplied list', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Do not add LengthLimiting formatter to the user supplied list', (WidgetTester tester) async { final List formatters = []; await tester.pumpWidget( @@ -7971,7 +8124,7 @@ void main() { await tester.pumpAndSettle(); } - testWidgets('using none enforcement.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('using none enforcement.', (WidgetTester tester) async { const MaxLengthEnforcement enforcement = MaxLengthEnforcement.none; await setupWidget(tester, enforcement); @@ -7991,7 +8144,7 @@ void main() { expect(state.currentTextEditingValue.composing, TextRange.empty); }); - testWidgets('using enforced.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('using enforced.', (WidgetTester tester) async { const MaxLengthEnforcement enforcement = MaxLengthEnforcement.enforced; await setupWidget(tester, enforcement); @@ -8015,7 +8168,7 @@ void main() { expect(state.currentTextEditingValue.composing, const TextRange(start: 3, end: 5)); }); - testWidgets('using truncateAfterCompositionEnds.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('using truncateAfterCompositionEnds.', (WidgetTester tester) async { const MaxLengthEnforcement enforcement = MaxLengthEnforcement.truncateAfterCompositionEnds; await setupWidget(tester, enforcement); @@ -8039,7 +8192,7 @@ void main() { expect(state.currentTextEditingValue.composing, TextRange.empty); }); - testWidgets('using default behavior for different platforms.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('using default behavior for different platforms.', (WidgetTester tester) async { await setupWidget(tester, null); final EditableTextState state = tester.state(find.byType(EditableText)); @@ -8072,7 +8225,7 @@ void main() { }); }); - testWidgets('disabled widget changes background color', (WidgetTester tester) async { + testWidgetsWithLeakTracking('disabled widget changes background color', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: Center( @@ -8148,7 +8301,7 @@ void main() { }); // Regression test for https://github.com/flutter/flutter/issues/78097. - testWidgets( + testWidgetsWithLeakTracking( 'still gets disabled background color when decoration is null', (WidgetTester tester) async { await tester.pumpWidget( @@ -8172,7 +8325,7 @@ void main() { }, ); - testWidgets('autofill info has placeholder text', (WidgetTester tester) async { + testWidgetsWithLeakTracking('autofill info has placeholder text', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoTextField( @@ -8188,7 +8341,7 @@ void main() { ); }); - testWidgets('textDirection is passed to EditableText', (WidgetTester tester) async { + testWidgetsWithLeakTracking('textDirection is passed to EditableText', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: Center( @@ -8216,7 +8369,7 @@ void main() { expect(rtlWidget.textDirection, TextDirection.rtl); }); - testWidgets('clipBehavior has expected defaults', (WidgetTester tester) async { + testWidgetsWithLeakTracking('clipBehavior has expected defaults', (WidgetTester tester) async { await tester.pumpWidget( const CupertinoApp( home: CupertinoTextField( @@ -8228,7 +8381,9 @@ void main() { expect(textField.clipBehavior, Clip.hardEdge); }); - testWidgets('Overflow clipBehavior none golden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Overflow clipBehavior none golden', (WidgetTester tester) async { + final OverflowWidgetTextEditingController controller = OverflowWidgetTextEditingController(); + addTearDown(controller.dispose); final Widget widget = CupertinoApp( home: RepaintBoundary( key: const ValueKey(1), @@ -8240,7 +8395,7 @@ void main() { // Make sure the input field is not high enough for the WidgetSpan. height: 50, child: CupertinoTextField( - controller: OverflowWidgetTextEditingController(), + controller: controller, clipBehavior: Clip.none, ), ), @@ -8262,10 +8417,11 @@ void main() { ); }); - testWidgets('can shift + tap to select with a keyboard (Apple platforms)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can shift + tap to select with a keyboard (Apple platforms)', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -8305,10 +8461,11 @@ void main() { expect(controller.selection.extentOffset, 4); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets('can shift + tap to select with a keyboard (non-Apple platforms)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can shift + tap to select with a keyboard (non-Apple platforms)', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -8350,11 +8507,13 @@ void main() { expect(controller.selection.extentOffset, 4); }, variant: const TargetPlatformVariant({ TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.linux, TargetPlatform.windows })); - testWidgets('shift tapping an unfocused field', (WidgetTester tester) async { + testWidgetsWithLeakTracking('shift tapping an unfocused field', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -8404,10 +8563,11 @@ void main() { expect(controller.selection.extentOffset, 20); }, variant: TargetPlatformVariant.all()); - testWidgets('can shift + tap + drag to select with a keyboard (Apple platforms)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can shift + tap + drag to select with a keyboard (Apple platforms)', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS; await tester.pumpWidget( CupertinoApp( @@ -8510,10 +8670,11 @@ void main() { expect(controller.selection.extentOffset, 26); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets('can shift + tap + drag to select with a keyboard (non-Apple platforms)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can shift + tap + drag to select with a keyboard (non-Apple platforms)', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); final bool isTargetPlatformMobile = defaultTargetPlatform == TargetPlatform.android || defaultTargetPlatform == TargetPlatform.fuchsia; await tester.pumpWidget( @@ -8617,10 +8778,11 @@ void main() { expect(controller.selection.extentOffset, 26); }, variant: const TargetPlatformVariant({ TargetPlatform.linux, TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.windows })); - testWidgets('can shift + tap + drag to select with a keyboard, reversed (Apple platforms)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can shift + tap + drag to select with a keyboard, reversed (Apple platforms)', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS; await tester.pumpWidget( CupertinoApp( @@ -8724,10 +8886,11 @@ void main() { expect(controller.selection.extentOffset, 14); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets('can shift + tap + drag to select with a keyboard, reversed (non-Apple platforms)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can shift + tap + drag to select with a keyboard, reversed (non-Apple platforms)', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'Atwater Peel Sherbrooke Bonaventure', ); + addTearDown(controller.dispose); final bool isTargetPlatformMobile = defaultTargetPlatform == TargetPlatform.android || defaultTargetPlatform == TargetPlatform.fuchsia; await tester.pumpWidget( @@ -8832,10 +8995,11 @@ void main() { }, variant: const TargetPlatformVariant({ TargetPlatform.linux, TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.windows })); // Regression test for https://github.com/flutter/flutter/issues/101587. - testWidgets('Right clicking menu behavior', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Right clicking menu behavior', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'blah1 blah2', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -8910,10 +9074,12 @@ void main() { ); group('Right click focus', () { - testWidgets('Can right click to focus multiple times', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can right click to focus multiple times', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/pull/103228 final FocusNode focusNode1 = FocusNode(); final FocusNode focusNode2 = FocusNode(); + addTearDown(focusNode1.dispose); + addTearDown(focusNode2.dispose); final UniqueKey key1 = UniqueKey(); final UniqueKey key2 = UniqueKey(); await tester.pumpWidget( @@ -8965,12 +9131,15 @@ void main() { expect(focusNode2.hasFocus, isFalse); }); - testWidgets('Can right click to focus on previously selected word on Apple platforms', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can right click to focus on previously selected word on Apple platforms', (WidgetTester tester) async { final FocusNode focusNode1 = FocusNode(); final FocusNode focusNode2 = FocusNode(); + addTearDown(focusNode1.dispose); + addTearDown(focusNode2.dispose); final TextEditingController controller = TextEditingController( text: 'first second', ); + addTearDown(controller.dispose); final UniqueKey key1 = UniqueKey(); await tester.pumpWidget( CupertinoApp( @@ -9065,8 +9234,9 @@ void main() { }); group('context menu', () { - testWidgets('builds CupertinoAdaptiveTextSelectionToolbar by default', (WidgetTester tester) async { + testWidgetsWithLeakTracking('builds CupertinoAdaptiveTextSelectionToolbar by default', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(text: ''); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Column( @@ -9095,9 +9265,10 @@ void main() { skip: kIsWeb, // [intended] on web the browser handles the context menu. ); - testWidgets('contextMenuBuilder is used in place of the default text selection toolbar', (WidgetTester tester) async { + testWidgetsWithLeakTracking('contextMenuBuilder is used in place of the default text selection toolbar', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final TextEditingController controller = TextEditingController(text: ''); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Column( @@ -9138,7 +9309,7 @@ void main() { final Widget fakeMagnifier = Container(key: UniqueKey()); group('magnifier builder', () { - testWidgets('should build custom magnifier if given', (WidgetTester tester) async { + testWidgetsWithLeakTracking('should build custom magnifier if given', (WidgetTester tester) async { final Widget customMagnifier = Container( key: UniqueKey(), ); @@ -9153,17 +9324,19 @@ void main() { final BuildContext context = tester.firstElement(find.byType(Placeholder)); + final ValueNotifier magnifierInfo = ValueNotifier(MagnifierInfo.empty); + addTearDown(magnifierInfo.dispose); expect( defaultCupertinoTextField.magnifierConfiguration!.magnifierBuilder( context, MagnifierController(), - ValueNotifier(MagnifierInfo.empty), + magnifierInfo, ), isA().having((Widget widget) => widget.key, 'key', equals(customMagnifier.key))); }); group('defaults', () { - testWidgets('should build CupertinoMagnifier on iOS and Android', (WidgetTester tester) async { + testWidgetsWithLeakTracking('should build CupertinoMagnifier on iOS and Android', (WidgetTester tester) async { await tester.pumpWidget(const CupertinoApp( home: CupertinoTextField(), )); @@ -9171,11 +9344,13 @@ void main() { final BuildContext context = tester.firstElement(find.byType(CupertinoTextField)); final EditableText editableText = tester.widget(find.byType(EditableText)); + final ValueNotifier magnifierInfo = ValueNotifier(MagnifierInfo.empty); + addTearDown(magnifierInfo.dispose); expect( editableText.magnifierConfiguration.magnifierBuilder( context, MagnifierController(), - ValueNotifier(MagnifierInfo.empty), + magnifierInfo, ), isA()); }, @@ -9183,7 +9358,7 @@ void main() { {TargetPlatform.iOS, TargetPlatform.android})); }); - testWidgets('should build nothing on all platforms but iOS and Android', (WidgetTester tester) async { + testWidgetsWithLeakTracking('should build nothing on all platforms but iOS and Android', (WidgetTester tester) async { await tester.pumpWidget(const CupertinoApp( home: CupertinoTextField(), )); @@ -9191,11 +9366,13 @@ void main() { final BuildContext context = tester.firstElement(find.byType(CupertinoTextField)); final EditableText editableText = tester.widget(find.byType(EditableText)); + final ValueNotifier magnifierInfo = ValueNotifier(MagnifierInfo.empty); + addTearDown(magnifierInfo.dispose); expect( editableText.magnifierConfiguration.magnifierBuilder( context, MagnifierController(), - ValueNotifier(MagnifierInfo.empty), + magnifierInfo, ), isNull); }, @@ -9203,9 +9380,10 @@ void main() { excluding: {TargetPlatform.iOS, TargetPlatform.android})); }); - testWidgets('Can drag handles to show, unshow, and update magnifier', + testWidgetsWithLeakTracking('Can drag handles to show, unshow, and update magnifier', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: CupertinoPageScaffold( @@ -9270,8 +9448,9 @@ void main() { expect(find.byKey(fakeMagnifier.key!), findsNothing); }, variant: TargetPlatformVariant.only(TargetPlatform.iOS)); - testWidgets('Can drag to show, unshow, and update magnifier', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can drag to show, unshow, and update magnifier', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -9369,8 +9548,9 @@ void main() { expect(find.byKey(fakeMagnifier.key!), findsNothing); }, variant: const TargetPlatformVariant({ TargetPlatform.android, TargetPlatform.iOS })); - testWidgets('Can long press to show, unshow, and update magnifier on non-Apple platforms', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can long press to show, unshow, and update magnifier on non-Apple platforms', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); final bool isTargetPlatformAndroid = defaultTargetPlatform == TargetPlatform.android; await tester.pumpWidget( CupertinoApp( @@ -9428,8 +9608,9 @@ void main() { expect(find.byKey(fakeMagnifier.key!), findsNothing); }, variant: const TargetPlatformVariant({ TargetPlatform.android })); - testWidgets('Can long press to show, unshow, and update magnifier on iOS', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can long press to show, unshow, and update magnifier on iOS', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); final bool isTargetPlatformAndroid = defaultTargetPlatform == TargetPlatform.android; await tester.pumpWidget( CupertinoApp( @@ -9490,8 +9671,9 @@ void main() { }); group('TapRegion integration', () { - testWidgets('Tapping outside loses focus on desktop', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Tapping outside loses focus on desktop', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(debugLabel: 'Test Node'); + addTearDown(focusNode.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -9516,8 +9698,9 @@ void main() { expect(focusNode.hasPrimaryFocus, isFalse); }, variant: TargetPlatformVariant.desktop()); - testWidgets("Tapping outside doesn't lose focus on mobile", (WidgetTester tester) async { + testWidgetsWithLeakTracking("Tapping outside doesn't lose focus on mobile", (WidgetTester tester) async { final FocusNode focusNode = FocusNode(debugLabel: 'Test Node'); + addTearDown(focusNode.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -9543,12 +9726,14 @@ void main() { expect(focusNode.hasPrimaryFocus, kIsWeb ? isFalse : isTrue); }, variant: TargetPlatformVariant.mobile()); - testWidgets("tapping on toolbar doesn't lose focus", (WidgetTester tester) async { + testWidgetsWithLeakTracking("tapping on toolbar doesn't lose focus", (WidgetTester tester) async { final TextEditingController controller; final EditableTextState state; controller = TextEditingController(text: 'A B C'); + addTearDown(controller.dispose); final FocusNode focusNode = FocusNode(debugLabel: 'Test Node'); + addTearDown(focusNode.dispose); await tester.pumpWidget( CupertinoApp( debugShowCheckedModeBanner: false, @@ -9602,9 +9787,10 @@ void main() { skip: kIsWeb, // [intended] The toolbar isn't rendered by Flutter on the web, it's rendered by the browser. ); - testWidgets("Tapping on border doesn't lose focus", + testWidgetsWithLeakTracking("Tapping on border doesn't lose focus", (WidgetTester tester) async { final FocusNode focusNode = FocusNode(debugLabel: 'Test Node'); + addTearDown(focusNode.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -9631,8 +9817,9 @@ void main() { }, variant: TargetPlatformVariant.all()); }); - testWidgets('Can drag handles to change selection correctly in multiline', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can drag handles to change selection correctly in multiline', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( @@ -9728,7 +9915,7 @@ void main() { } }); - testWidgets('placeholder style overflow works', (WidgetTester tester) async { + testWidgetsWithLeakTracking('placeholder style overflow works', (WidgetTester tester) async { final String placeholder = 'hint text' * 20; const TextStyle placeholderStyle = TextStyle( fontSize: 14.0, @@ -9752,7 +9939,7 @@ void main() { expect(placeholderWidget.style!.overflow, placeholderStyle.overflow); }); - testWidgets('tapping on a misspelled word on iOS hides the handles and shows red selection', (WidgetTester tester) async { + testWidgetsWithLeakTracking('tapping on a misspelled word on iOS hides the handles and shows red selection', (WidgetTester tester) async { tester.binding.platformDispatcher.nativeSpellCheckServiceDefinedTestValue = true; // The default derived color for the iOS text selection highlight. @@ -9760,6 +9947,7 @@ void main() { final TextEditingController controller = TextEditingController( text: 'test test testt', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -9825,10 +10013,11 @@ void main() { skip: kIsWeb, // [intended] ); - testWidgets('text selection toolbar is hidden on tap down', (WidgetTester tester) async { + testWidgetsWithLeakTracking('text selection toolbar is hidden on tap down', (WidgetTester tester) async { final TextEditingController controller = TextEditingController( text: 'blah1 blah2', ); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Center( @@ -9870,9 +10059,10 @@ void main() { variant: TargetPlatformVariant.all(excluding: { TargetPlatform.iOS }), ); - testWidgets('Does not shrink in height when enters text when there is large single-line placeholder', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Does not shrink in height when enters text when there is large single-line placeholder', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/133241. final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Align( @@ -9894,8 +10084,9 @@ void main() { expect(rectWithPlaceholder, rectWithText); }); - testWidgets('Does not match the height of a multiline placeholder', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Does not match the height of a multiline placeholder', (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); await tester.pumpWidget( CupertinoApp( home: Align( diff --git a/packages/flutter/test/material/dialog_test.dart b/packages/flutter/test/material/dialog_test.dart index 0a162059412d9..ab50283e557d2 100644 --- a/packages/flutter/test/material/dialog_test.dart +++ b/packages/flutter/test/material/dialog_test.dart @@ -111,7 +111,7 @@ void main() { expect(materialWidget.color, customColor); }); - testWidgetsWithLeakTracking('Dialog Defaults', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material2 - Dialog Defaults', (WidgetTester tester) async { const AlertDialog dialog = AlertDialog( title: Text('Title'), content: Text('Y'), @@ -131,10 +131,14 @@ void main() { find.descendant(of: find.byType(Dialog), matching: find.byType(Material)), ); expect(bottomLeft.dy, 360.0); + }); - await tester.tapAt(const Offset(10.0, 10.0)); - await tester.pumpAndSettle(); - + testWidgetsWithLeakTracking('Material3 - Dialog Defaults', (WidgetTester tester) async { + const AlertDialog dialog = AlertDialog( + title: Text('Title'), + content: Text('Y'), + actions: [ ], + ); await tester.pumpWidget(_buildAppWithDialog(dialog, theme: material3Theme)); await tester.tap(find.text('X')); @@ -146,9 +150,8 @@ void main() { expect(material3Widget.elevation, 6.0); }); - testWidgetsWithLeakTracking('Dialog.fullscreen Defaults', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material2 - Dialog.fullscreen Defaults', (WidgetTester tester) async { const String dialogTextM2 = 'Fullscreen Dialog - M2'; - const String dialogTextM3 = 'Fullscreen Dialog - M3'; await tester.pumpWidget(_buildAppWithDialog( theme: material2Theme, @@ -162,7 +165,7 @@ void main() { expect(find.text(dialogTextM2), findsOneWidget); - Material materialWidget = _getMaterialFromDialog(tester); + final Material materialWidget = _getMaterialFromDialog(tester); expect(materialWidget.color, Colors.grey[800]); // Try to dismiss the fullscreen dialog with the escape key. @@ -170,6 +173,10 @@ void main() { await tester.pumpAndSettle(); expect(find.text(dialogTextM2), findsNothing); + }); + + testWidgetsWithLeakTracking('Material3 - Dialog.fullscreen Defaults', (WidgetTester tester) async { + const String dialogTextM3 = 'Fullscreen Dialog - M3'; await tester.pumpWidget(_buildAppWithDialog( theme: material3Theme, @@ -183,7 +190,7 @@ void main() { expect(find.text(dialogTextM3), findsOneWidget); - materialWidget = _getMaterialFromDialog(tester); + final Material materialWidget = _getMaterialFromDialog(tester); expect(materialWidget.color, material3Theme.colorScheme.surface); // Try to dismiss the fullscreen dialog with the escape key. @@ -644,7 +651,7 @@ void main() { expect(actionsSize.width, dialogSize.width - (30.0 * 2)); }); - testWidgetsWithLeakTracking('AlertDialog.buttonPadding defaults', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material2 - AlertDialog.buttonPadding defaults', (WidgetTester tester) async { final GlobalKey key1 = GlobalKey(); final GlobalKey key2 = GlobalKey(); @@ -700,10 +707,28 @@ void main() { tester.getBottomRight(find.byKey(key2)).dx, tester.getBottomRight(_findButtonBar()).dx - 8.0, ); // right + }); - // Dismiss it and test material 3 dialog - await tester.tapAt(const Offset(10.0, 10.0)); - await tester.pumpAndSettle(); + testWidgetsWithLeakTracking('Material3 - AlertDialog.buttonPadding defaults', (WidgetTester tester) async { + final GlobalKey key1 = GlobalKey(); + final GlobalKey key2 = GlobalKey(); + + final AlertDialog dialog = AlertDialog( + title: const Text('title'), + content: const Text('content'), + actions: [ + ElevatedButton( + key: key1, + onPressed: () {}, + child: const Text('button 1'), + ), + ElevatedButton( + key: key2, + onPressed: () {}, + child: const Text('button 2'), + ), + ], + ); await tester.pumpWidget(_buildAppWithDialog(dialog, theme: material3Theme)); diff --git a/packages/flutter/test/material/drawer_test.dart b/packages/flutter/test/material/drawer_test.dart index a83b1bef962bd..7595f7aabca92 100644 --- a/packages/flutter/test/material/drawer_test.dart +++ b/packages/flutter/test/material/drawer_test.dart @@ -10,7 +10,7 @@ import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import '../widgets/semantics_tester.dart'; void main() { - testWidgetsWithLeakTracking('Drawer control test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material2 - Drawer control test', (WidgetTester tester) async { const Key containerKey = Key('container'); await tester.pumpWidget( @@ -58,6 +58,54 @@ void main() { expect(find.text('header'), findsOneWidget); }); + testWidgetsWithLeakTracking('Material3 - Drawer control test', (WidgetTester tester) async { + const Key containerKey = Key('container'); + + await tester.pumpWidget( + MaterialApp( + theme: ThemeData(useMaterial3: true), + home: Scaffold( + drawer: Drawer( + child: ListView( + children: [ + DrawerHeader( + child: Container( + key: containerKey, + child: const Text('header'), + ), + ), + const ListTile( + leading: Icon(Icons.archive), + title: Text('Archive'), + ), + ], + ), + ), + ), + ), + ); + + expect(find.text('Archive'), findsNothing); + final ScaffoldState state = tester.firstState(find.byType(Scaffold)); + state.openDrawer(); + + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); + expect(find.text('Archive'), findsOneWidget); + + RenderBox box = tester.renderObject(find.byType(DrawerHeader)); + expect(box.size.height, equals(160.0 + 8.0 + 1.0)); // height + bottom margin + bottom edge + + final double drawerWidth = box.size.width; + final double drawerHeight = box.size.height; + + box = tester.renderObject(find.byKey(containerKey)); + expect(box.size.width, equals(drawerWidth - 2 * 16.0)); + expect(box.size.height, equals(drawerHeight - 2 * 16.0 - 1.0)); // Header divider thickness is 1.0 in Material 3. + + expect(find.text('header'), findsOneWidget); + }); + testWidgetsWithLeakTracking('Drawer dismiss barrier has label', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( @@ -570,7 +618,7 @@ void main() { expect(box.size.width, equals(smallWidth)); }); - testWidgetsWithLeakTracking('Drawer default shape (ltr)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material3 - Drawer default shape (ltr)', (WidgetTester tester) async { await tester.pumpWidget( MaterialApp( theme: ThemeData(useMaterial3: true), @@ -630,7 +678,7 @@ void main() { ); }); - testWidgetsWithLeakTracking('Drawer default shape (rtl)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material3 - Drawer default shape (rtl)', (WidgetTester tester) async { await tester.pumpWidget( MaterialApp( theme: ThemeData(useMaterial3: true), @@ -690,7 +738,7 @@ void main() { ); }); - testWidgetsWithLeakTracking('Drawer clip behavior', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material3 - Drawer clip behavior', (WidgetTester tester) async { await tester.pumpWidget( MaterialApp( theme: ThemeData(useMaterial3: true), @@ -746,7 +794,7 @@ void main() { // support is deprecated and the APIs are removed, these tests // can be deleted. - testWidgetsWithLeakTracking('Drawer default shape', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material2 - Drawer default shape', (WidgetTester tester) async { await tester.pumpWidget( MaterialApp( theme: ThemeData(useMaterial3: false), @@ -787,7 +835,7 @@ void main() { expect(material.shape, null); }); - testWidgetsWithLeakTracking('Drawer clip behavior', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material2 - Drawer clip behavior', (WidgetTester tester) async { await tester.pumpWidget( MaterialApp( theme: ThemeData(useMaterial3: false), diff --git a/packages/flutter/test/material/navigation_bar_test.dart b/packages/flutter/test/material/navigation_bar_test.dart index f38a4830f6617..598b9a3664ece 100644 --- a/packages/flutter/test/material/navigation_bar_test.dart +++ b/packages/flutter/test/material/navigation_bar_test.dart @@ -977,6 +977,43 @@ void main() { expect(_getIndicatorDecoration(tester)?.shape, shape); }); + testWidgetsWithLeakTracking('Destinations respect their disabled state', (WidgetTester tester) async { + int selectedIndex = 0; + + await tester.pumpWidget( + _buildWidget( + NavigationBar( + destinations: const [ + NavigationDestination( + icon: Icon(Icons.ac_unit), + label: 'AC', + ), + NavigationDestination( + icon: Icon(Icons.access_alarm), + label: 'Alarm', + ), + NavigationDestination( + icon: Icon(Icons.bookmark), + label: 'Bookmark', + enabled: false, + ), + ], + onDestinationSelected: (int i) => selectedIndex = i, + selectedIndex: selectedIndex, + ), + ) + ); + + await tester.tap(find.text('AC')); + expect(selectedIndex, 0); + + await tester.tap(find.text('Alarm')); + expect(selectedIndex, 1); + + await tester.tap(find.text('Bookmark')); + expect(selectedIndex, 1); + }); + group('Material 2', () { // These tests are only relevant for Material 2. Once Material 2 // support is deprecated and the APIs are removed, these tests diff --git a/packages/flutter/test/material/progress_indicator_test.dart b/packages/flutter/test/material/progress_indicator_test.dart index 12ec99d24994c..7537bf97871e1 100644 --- a/packages/flutter/test/material/progress_indicator_test.dart +++ b/packages/flutter/test/material/progress_indicator_test.dart @@ -1183,6 +1183,75 @@ void main() { expect(tester.getSize(find.byType(CircularProgressIndicator)), const Size(36, 36)); }); + + testWidgetsWithLeakTracking('RefreshProgressIndicator using fields correctly', (WidgetTester tester) async { + Future pumpIndicator(RefreshProgressIndicator indicator) { + return tester.pumpWidget(Theme(data: theme, child: indicator)); + } + + // With default values. + await pumpIndicator(const RefreshProgressIndicator()); + Material material = tester.widget( + find.descendant( + of: find.byType(RefreshProgressIndicator), + matching: find.byType(Material), + ), + ); + Container container = tester.widget( + find.descendant( + of: find.byType(RefreshProgressIndicator), + matching: find.byType(Container), + ), + ); + Padding padding = tester.widget( + find.descendant( + of: find.descendant( + of: find.byType(RefreshProgressIndicator), + matching: find.byType(Material), + ), + matching: find.byType(Padding), + ), + ); + expect(material.elevation, 2.0); + expect(container.margin, const EdgeInsets.all(4.0)); + expect(padding.padding, const EdgeInsets.all(12.0)); + + // With values provided. + const double testElevation = 1.0; + const EdgeInsetsGeometry testIndicatorMargin = EdgeInsets.all(6.0); + const EdgeInsetsGeometry testIndicatorPadding = EdgeInsets.all(10.0); + await pumpIndicator( + const RefreshProgressIndicator( + elevation: testElevation, + indicatorMargin: testIndicatorMargin, + indicatorPadding: testIndicatorPadding, + ), + ); + material = tester.widget( + find.descendant( + of: find.byType(RefreshProgressIndicator), + matching: find.byType(Material), + ), + ); + container = tester.widget( + find.descendant( + of: find.byType(RefreshProgressIndicator), + matching: find.byType(Container), + ), + ); + padding = tester.widget( + find.descendant( + of: find.descendant( + of: find.byType(RefreshProgressIndicator), + matching: find.byType(Material), + ), + matching: find.byType(Padding), + ), + ); + expect(material.elevation, testElevation); + expect(container.margin, testIndicatorMargin); + expect(padding.padding, testIndicatorPadding); + }); } class _RefreshProgressIndicatorGolden extends StatefulWidget { diff --git a/packages/flutter/test/material/range_slider_test.dart b/packages/flutter/test/material/range_slider_test.dart index 5bedc0cad01af..bd1c528065239 100644 --- a/packages/flutter/test/material/range_slider_test.dart +++ b/packages/flutter/test/material/range_slider_test.dart @@ -2541,7 +2541,7 @@ void main() { ); }); - testWidgetsWithLeakTracking('RangeSlider onChangeStart and onChangeEnd fire once', (WidgetTester tester) async { + testWidgetsWithLeakTracking('RangeSlider onChangeStart and onChangeEnd fire once', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/128433 int startFired = 0; @@ -2581,4 +2581,34 @@ void main() { expect(startFired, equals(1)); expect(endFired, equals(1)); }); + + testWidgetsWithLeakTracking('RangeSlider in a ListView does not throw an exception', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/126648 + + await tester.pumpWidget( + MaterialApp( + home: Directionality( + textDirection: TextDirection.ltr, + child: Material( + child: ListView( + children: [ + const SizedBox( + height: 600, + child: Placeholder(), + ), + RangeSlider( + values: const RangeValues(40, 80), + max: 100, + onChanged: (RangeValues newValue) { }, + ), + ], + ), + ), + ), + ), + ); + + // No exception should be thrown. + expect(tester.takeException(), null); + }); } diff --git a/packages/flutter/test/material/scaffold_test.dart b/packages/flutter/test/material/scaffold_test.dart index b883025a5d207..0fbc94508764f 100644 --- a/packages/flutter/test/material/scaffold_test.dart +++ b/packages/flutter/test/material/scaffold_test.dart @@ -273,6 +273,7 @@ void main() { testWidgetsWithLeakTracking('Floating action button shrinks when bottom sheet becomes dominant', (WidgetTester tester) async { final DraggableScrollableController draggableController = DraggableScrollableController(); + addTearDown(draggableController.dispose); const double kBottomSheetDominatesPercentage = 0.3; await tester.pumpWidget(MaterialApp(home: Scaffold( @@ -312,6 +313,7 @@ void main() { testWidgetsWithLeakTracking('Scaffold shows scrim when bottom sheet becomes dominant', (WidgetTester tester) async { final DraggableScrollableController draggableController = DraggableScrollableController(); + addTearDown(draggableController.dispose); const double kBottomSheetDominatesPercentage = 0.3; const double kMinBottomSheetScrimOpacity = 0.1; const double kMaxBottomSheetScrimOpacity = 0.6; @@ -2762,6 +2764,7 @@ void main() { testWidgetsWithLeakTracking('showBottomSheet removes scrim when draggable sheet is dismissed', (WidgetTester tester) async { final DraggableScrollableController draggableController = DraggableScrollableController(); + addTearDown(draggableController.dispose); final GlobalKey scaffoldKey = GlobalKey(); PersistentBottomSheetController? sheetController; diff --git a/packages/flutter/test/material/search_anchor_test.dart b/packages/flutter/test/material/search_anchor_test.dart index c2af15aad9ac1..3398560998b7a 100644 --- a/packages/flutter/test/material/search_anchor_test.dart +++ b/packages/flutter/test/material/search_anchor_test.dart @@ -2055,6 +2055,117 @@ void main() { expect(inputText.style.color, theme.colorScheme.onSurface); }); }); + + testWidgets('SearchAnchor view respects theme brightness', (WidgetTester tester) async { + Widget buildSearchAnchor(ThemeData theme) { + return MaterialApp( + theme: theme, + home: Center( + child: Material( + child: SearchAnchor( + builder: (BuildContext context, SearchController controller) { + return IconButton( + icon: const Icon(Icons.ac_unit), + onPressed: () { + controller.openView(); + }, + ); + }, + suggestionsBuilder: (BuildContext context, SearchController controller) { + return []; + }, + ), + ), + ), + ); + } + + ThemeData theme = ThemeData(brightness: Brightness.light); + await tester.pumpWidget(buildSearchAnchor(theme)); + + // Open the search view. + await tester.tap(find.widgetWithIcon(IconButton, Icons.ac_unit)); + await tester.pumpAndSettle(); + + // Test the search view background color. + Material material = getSearchViewMaterial(tester); + expect(material.color, theme.colorScheme.surface); + + // Change the theme brightness. + theme = ThemeData(brightness: Brightness.dark); + await tester.pumpWidget(buildSearchAnchor(theme)); + await tester.pumpAndSettle(); + + // Test the search view background color. + material = getSearchViewMaterial(tester); + expect(material.color, theme.colorScheme.surface); + }); + + testWidgets('Search view widgets can inherit local themes', (WidgetTester tester) async { + final ThemeData globalTheme = ThemeData(colorSchemeSeed: Colors.red); + final ThemeData localTheme = ThemeData( + colorSchemeSeed: Colors.green, + iconButtonTheme: IconButtonThemeData( + style: IconButton.styleFrom( + backgroundColor: const Color(0xffffff00) + ), + ), + cardTheme: const CardTheme(color: Color(0xff00ffff)), + ); + Widget buildSearchAnchor() { + return MaterialApp( + theme: globalTheme, + home: Center( + child: Builder( + builder: (BuildContext context) { + return Theme( + data: localTheme, + child: Material( + child: SearchAnchor.bar( + suggestionsBuilder: (BuildContext context, SearchController controller) { + return [ + Card( + child: ListTile( + onTap: () {}, + title: const Text('Item 1'), + ), + ), + ]; + }, + ), + ), + ); + } + ), + ), + ); + } + + await tester.pumpWidget(buildSearchAnchor()); + + // Open the search view. + await tester.tap(find.byType(SearchBar)); + await tester.pumpAndSettle(); + + // Test the search view background color. + final Material searchViewMaterial = getSearchViewMaterial(tester); + expect(searchViewMaterial.color, localTheme.colorScheme.surface); + + // Test the search view icons background color. + final Material iconButtonMaterial = tester.widget(find.descendant( + of: find.byType(IconButton), + matching: find.byType(Material), + ).first); + expect(find.byWidget(iconButtonMaterial), findsOneWidget); + expect(iconButtonMaterial.color, localTheme.iconButtonTheme.style?.backgroundColor?.resolve({})); + + // Test the suggestion card color. + final Material suggestionMaterial = tester.widget(find.descendant( + of: find.byType(Card), + matching: find.byType(Material), + ).first); + expect(suggestionMaterial.color, localTheme.cardTheme.color); + }); } Future checkSearchBarDefaults(WidgetTester tester, ColorScheme colorScheme, Material material) async { diff --git a/packages/flutter/test/material/selection_area_test.dart b/packages/flutter/test/material/selection_area_test.dart index 8edb4b68d4bac..521a3ff66eca0 100644 --- a/packages/flutter/test/material/selection_area_test.dart +++ b/packages/flutter/test/material/selection_area_test.dart @@ -224,8 +224,14 @@ void main() { // Backwards selection. await gesture.down(textOffsetToPosition(paragraph, 3)); - await tester.pumpAndSettle(); - expect(content, isNull); + await tester.pump(); + await gesture.up(); + await tester.pumpAndSettle(kDoubleTapTimeout); + expect(content, isNotNull); + expect(content!.plainText, ''); + + await gesture.down(textOffsetToPosition(paragraph, 3)); + await tester.pump(); await gesture.moveTo(textOffsetToPosition(paragraph, 0)); await gesture.up(); await tester.pump(); diff --git a/packages/flutter/test/material/tabs_test.dart b/packages/flutter/test/material/tabs_test.dart index 098ad754c954c..bc26ae7ff1a55 100644 --- a/packages/flutter/test/material/tabs_test.dart +++ b/packages/flutter/test/material/tabs_test.dart @@ -1643,6 +1643,54 @@ void main() { expect(pageController.viewportFraction, 1); }); + testWidgets('TabBarView viewportFraction can be updated', (WidgetTester tester) async { + // This is a regression test for https://github.com/flutter/flutter/issues/135557. + final List tabs = ['A', 'B', 'C']; + TabController? controller; + + Widget buildFrame(double viewportFraction) { + controller = _tabController( + vsync: const TestVSync(), + length: tabs.length, + initialIndex: 1, + ); + return boilerplate( + child: Column( + children: [ + TabBar( + tabs: tabs.map((String tab) => Tab(text: tab)).toList(), + controller: controller, + ), + SizedBox( + width: 400.0, + height: 400.0, + child: TabBarView( + viewportFraction: viewportFraction, + controller: controller, + children: const [ + Center(child: Text('0')), + Center(child: Text('1')), + Center(child: Text('2')), + ], + ), + ), + ], + ), + ); + } + + await tester.pumpWidget(buildFrame(0.8)); + PageView pageView = tester.widget(find.byType(PageView)); + PageController pageController = pageView.controller; + expect(pageController.viewportFraction, 0.8); + + // Rebuild with a different viewport fraction. + await tester.pumpWidget(buildFrame(0.5)); + pageView = tester.widget(find.byType(PageView)); + pageController = pageView.controller; + expect(pageController.viewportFraction, 0.5); + }); + testWidgets('TabBarView has clipBehavior Clip.hardEdge by default', (WidgetTester tester) async { final List tabs = [const Text('First'), const Text('Second')]; diff --git a/packages/flutter/test/rendering/paragraph_test.dart b/packages/flutter/test/rendering/paragraph_test.dart index a85d83ae39489..06aa6a151a3d9 100644 --- a/packages/flutter/test/rendering/paragraph_test.dart +++ b/packages/flutter/test/rendering/paragraph_test.dart @@ -978,7 +978,8 @@ void main() { granularity: TextGranularity.word, ), ); - expect(paragraph.selections.length, 0); // how []are you + expect(paragraph.selections.length, 1); // how []are you + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 4)); // Equivalent to sending shift + alt + arrow-left. registrar.selectables[0].dispatchSelectionEvent( diff --git a/packages/flutter/test/rendering/viewport_test.dart b/packages/flutter/test/rendering/viewport_test.dart index e2e00012721c6..b4cf6ae489c94 100644 --- a/packages/flutter/test/rendering/viewport_test.dart +++ b/packages/flutter/test/rendering/viewport_test.dart @@ -1586,6 +1586,14 @@ void main() { final double revealOffset = viewport.getOffsetToReveal(target, 0.0).offset; expect(revealOffset, -(300.0 + padding.horizontal) * 5 + 34.0 * 2); }); + + testWidgets('will not assert on mismatched axis', (WidgetTester tester) async { + await tester.pumpWidget(buildList(axis: Axis.vertical, reverse: true, reverseGrowth: true)); + final RenderAbstractViewport viewport = tester.allRenderObjects.whereType().first; + + final RenderObject target = tester.renderObject(find.text('Tile 0', skipOffstage: false)); + viewport.getOffsetToReveal(target, 0.0, axis: Axis.horizontal); + }); }); testWidgets('RenderViewportBase.showOnScreen reports the correct targetRect', (WidgetTester tester) async { diff --git a/packages/flutter/test/services/raw_keyboard_test.dart b/packages/flutter/test/services/raw_keyboard_test.dart index f5c4b38b4acf5..37b6d08605781 100644 --- a/packages/flutter/test/services/raw_keyboard_test.dart +++ b/packages/flutter/test/services/raw_keyboard_test.dart @@ -19,7 +19,7 @@ class _ModifierCheck { void main() { group('RawKeyboard', () { testWidgetsWithLeakTracking('The correct character is produced', (WidgetTester tester) async { - for (final String platform in ['linux', 'android', 'macos', 'fuchsia', 'windows']) { + for (final String platform in ['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) { String character = ''; void handleKey(RawKeyEvent event) { expect(event.character, equals(character), reason: 'on $platform'); @@ -34,7 +34,7 @@ void main() { }); testWidgetsWithLeakTracking('No character is produced for non-printables', (WidgetTester tester) async { - for (final String platform in ['linux', 'android', 'macos', 'fuchsia', 'windows', 'web']) { + for (final String platform in ['linux', 'android', 'macos', 'fuchsia', 'windows', 'web', 'ios']) { void handleKey(RawKeyEvent event) { expect(event.character, isNull, reason: 'on $platform'); } diff --git a/packages/flutter/test/widgets/animated_size_test.dart b/packages/flutter/test/widgets/animated_size_test.dart index 75a9272d05f8f..c48729e48e6fe 100644 --- a/packages/flutter/test/widgets/animated_size_test.dart +++ b/packages/flutter/test/widgets/animated_size_test.dart @@ -435,7 +435,7 @@ void main() { ); }); - testWidgets('disposes animation and controller', (WidgetTester tester) async { + testWidgetsWithLeakTracking('disposes animation and controller', (WidgetTester tester) async { await tester.pumpWidget( const Center( child: AnimatedSize( diff --git a/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart b/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart index c9da896314c61..bf7e87fd32083 100644 --- a/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart +++ b/packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart @@ -1681,7 +1681,9 @@ void main() { testWidgetsWithLeakTracking('DraggableScrollableSheet controller can be changed while animating', (WidgetTester tester) async { final DraggableScrollableController controller1 = DraggableScrollableController(); + addTearDown(controller1.dispose); final DraggableScrollableController controller2 = DraggableScrollableController(); + addTearDown(controller2.dispose); DraggableScrollableController controller = controller1; await tester.pumpWidget(MaterialApp( @@ -1733,4 +1735,11 @@ void main() { expect(controller1.isAttached, false); expect(controller2.isAttached, false); }); + + testWidgetsWithLeakTracking('$DraggableScrollableController dispatches creation in constructor.', (WidgetTester widgetTester) async { + await expectLater( + await memoryEvents(() async => DraggableScrollableController().dispose(), DraggableScrollableController), + areCreateAndDispose, + ); + }); } diff --git a/packages/flutter/test/widgets/editable_text_test.dart b/packages/flutter/test/widgets/editable_text_test.dart index dc5b7fb797ad4..e3dfc46c78e6d 100644 --- a/packages/flutter/test/widgets/editable_text_test.dart +++ b/packages/flutter/test/widgets/editable_text_test.dart @@ -1559,7 +1559,9 @@ void main() { expect(tester.testTextInput.setClientArgs!['inputAction'], equals('TextInputAction.done')); }); - // Test case for https://github.com/flutter/flutter/issues/123523. + // Test case for + // https://github.com/flutter/flutter/issues/123523 + // https://github.com/flutter/flutter/issues/134846 . testWidgetsWithLeakTracking( 'The focus and callback behavior are correct when TextInputClient.onConnectionClosed message received', (WidgetTester tester) async { @@ -1597,17 +1599,9 @@ void main() { editableText.connectionClosed(); await tester.pump(); - if (kIsWeb) { - expect(onSubmittedInvoked, isTrue); - expect(onEditingCompleteInvoked, isTrue); - // Because we add the onEditingComplete and we didn't unfocus there, so focus still exists. - expect(focusNode.hasFocus, isTrue); - } else { - // For mobile and other platforms, calling connectionClosed will only unfocus. - expect(focusNode.hasFocus, isFalse); - expect(onEditingCompleteInvoked, isFalse); - expect(onSubmittedInvoked, isFalse); - } + expect(focusNode.hasFocus, isFalse); + expect(onEditingCompleteInvoked, isFalse); + expect(onSubmittedInvoked, isFalse); }); testWidgetsWithLeakTracking('connection is closed when TextInputClient.onConnectionClosed message received', (WidgetTester tester) async { diff --git a/packages/flutter/test/widgets/ensure_visible_test.dart b/packages/flutter/test/widgets/ensure_visible_test.dart index 329388ee11a88..97898ca632f71 100644 --- a/packages/flutter/test/widgets/ensure_visible_test.dart +++ b/packages/flutter/test/widgets/ensure_visible_test.dart @@ -9,6 +9,8 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; +import 'two_dimensional_utils.dart'; + Finder findKey(int i) => find.byKey(ValueKey(i), skipOffstage: false); Widget buildSingleChildScrollView(Axis scrollDirection, { bool reverse = false }) { @@ -1051,4 +1053,279 @@ void main() { expect(tester.getTopLeft(findKey(-3)).dy, equals(100.0)); }); }); + + group('TwoDimensionalViewport ensureVisible', () { + Finder findKey(ChildVicinity vicinity) { + return find.byKey(ValueKey(vicinity)); + } + + BuildContext findContext(WidgetTester tester, ChildVicinity vicinity) { + return tester.element(findKey(vicinity)); + } + + testWidgets('Axis.vertical', (WidgetTester tester) async { + await tester.pumpWidget(simpleBuilderTest(useCacheExtent: true)); + + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 0, yIndex: 0)), + ); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 0))).dy, + equals(0.0), + ); + // (0, 3) is in the cache extent, and will be brought into view next + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 3))).dy, + equals(600.0), + ); + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 0, yIndex: 3)), + ); + await tester.pump(); + // Now in view at top edge of viewport + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 3))).dy, + equals(0.0), + ); + + // If already visible, no change + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 0, yIndex: 3)), + ); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 3))).dy, + equals(0.0), + ); + }); + + testWidgets('Axis.horizontal', (WidgetTester tester) async { + await tester.pumpWidget(simpleBuilderTest(useCacheExtent: true)); + + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 1, yIndex: 0)), + ); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 1, yIndex: 0))).dx, + equals(0.0), + ); + // (5, 0) is now in the cache extent, and will be brought into view next + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 5, yIndex: 0))).dx, + equals(800.0), + ); + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 5, yIndex: 0)), + alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd, + ); + await tester.pump(); + // Now in view at trailing edge of viewport + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 5, yIndex: 0))).dx, + equals(600.0), + ); + + // If already in position, no change + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 5, yIndex: 0)), + alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd, + ); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 5, yIndex: 0))).dx, + equals(600.0), + ); + }); + + testWidgets('both axes', (WidgetTester tester) async { + await tester.pumpWidget(simpleBuilderTest(useCacheExtent: true)); + + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 1, yIndex: 1)), + ); + await tester.pump(); + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 1, yIndex: 1))), + const Rect.fromLTRB(0.0, 0.0, 200.0, 200.0), + ); + // (5, 4) is in the cache extent, and will be brought into view next + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 5, yIndex: 4))), + const Rect.fromLTRB(800.0, 600.0, 1000.0, 800.0), + ); + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 5, yIndex: 4)), + alignment: 1.0, // Same as ScrollAlignmentPolicy.keepVisibleAtEnd + ); + await tester.pump(); + // Now in view at bottom trailing corner of viewport + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 5, yIndex: 4))), + const Rect.fromLTRB(600.0, 400.0, 800.0, 600.0), + ); + + // If already visible, no change + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 5, yIndex: 4)), + alignment: 1.0, + ); + await tester.pump(); + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 5, yIndex: 4))), + const Rect.fromLTRB(600.0, 400.0, 800.0, 600.0), + ); + }); + + testWidgets('Axis.vertical reverse', (WidgetTester tester) async { + await tester.pumpWidget(simpleBuilderTest( + verticalDetails: const ScrollableDetails.vertical(reverse: true), + useCacheExtent: true, + )); + + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 0))).dy, + equals(400.0), + ); + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 0, yIndex: 0)), + ); + await tester.pump(); + // Already visible so no change. + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 0))).dy, + equals(400.0), + ); + // (0, 3) is in the cache extent, and will be brought into view next + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 3))).dy, + equals(-200.0), + ); + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 0, yIndex: 3)), + ); + await tester.pump(); + // Now in view at bottom edge of viewport since we are reversed + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 3))).dy, + equals(400.0), + ); + + // If already visible, no change + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 0, yIndex: 3)), + ); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 3))).dy, + equals(400.0), + ); + }); + + testWidgets('Axis.horizontal reverse', (WidgetTester tester) async { + await tester.pumpWidget(simpleBuilderTest( + horizontalDetails: const ScrollableDetails.horizontal(reverse: true), + useCacheExtent: true, + )); + + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 0))).dx, + equals(600.0), + ); + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 0, yIndex: 0)), + ); + await tester.pump(); + // Already visible so no change. + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 0))).dx, + equals(600.0), + ); + // (4, 0) is in the cache extent, and will be brought into view next + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 4, yIndex: 0))).dx, + equals(-200.0), + ); + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 4, yIndex: 0)), + ); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 4, yIndex: 0))).dx, + equals(200.0), + ); + + // If already visible, no change + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 4, yIndex: 0)), + ); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 4, yIndex: 0))).dx, + equals(200.0), + ); + }); + + testWidgets('both axes reverse', (WidgetTester tester) async { + await tester.pumpWidget(simpleBuilderTest( + verticalDetails: const ScrollableDetails.vertical(reverse: true), + horizontalDetails: const ScrollableDetails.horizontal(reverse: true), + useCacheExtent: true, + )); + + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 1, yIndex: 1)), + ); + await tester.pump(); + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 1, yIndex: 1))), + const Rect.fromLTRB(600.0, 400.0, 800.0, 600.0), + ); + // (5, 4) is in the cache extent, and will be brought into view next + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 5, yIndex: 4))), + const Rect.fromLTRB(-200.0, -200.0, 0.0, 0.0), + ); + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 5, yIndex: 4)), + alignment: 1.0, // Same as ScrollAlignmentPolicy.keepVisibleAtEnd + ); + await tester.pump(); + // Now in view at trailing corner of viewport + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 5, yIndex: 4))), + const Rect.fromLTRB(0.0, 0.0, 200.0, 200.0), + ); + + // If already visible, no change + Scrollable.ensureVisible(findContext( + tester, + const ChildVicinity(xIndex: 5, yIndex: 4)), + alignment: 1.0, + ); + await tester.pump(); + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 5, yIndex: 4))), + const Rect.fromLTRB(0.0, 0.0, 200.0, 200.0), + ); + }); + }); } diff --git a/packages/flutter/test/widgets/framework_test.dart b/packages/flutter/test/widgets/framework_test.dart index d66f3466911b6..d80e1e56670b7 100644 --- a/packages/flutter/test/widgets/framework_test.dart +++ b/packages/flutter/test/widgets/framework_test.dart @@ -1062,13 +1062,14 @@ void main() { element.createChild(0, after: null); }); - testWidgets('GlobalKey - re-attach child to new parents, and the old parent is deactivated(unmounted)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('GlobalKey - re-attach child to new parents, and the old parent is deactivated(unmounted)', (WidgetTester tester) async { // This is a regression test for https://github.com/flutter/flutter/issues/62055 const Key key1 = GlobalObjectKey('key1'); const Key key2 = GlobalObjectKey('key2'); late StateSetter setState; int tabBarViewCnt = 2; TabController tabController = TabController(length: tabBarViewCnt, vsync: const TestVSync()); + addTearDown(tabController.dispose); await tester.pumpWidget(Directionality( textDirection: TextDirection.ltr, @@ -1101,6 +1102,7 @@ void main() { setState(() { tabBarViewCnt = 1; tabController = TabController(length: tabBarViewCnt, vsync: const TestVSync()); + addTearDown(tabController.dispose); }); await tester.pump(const Duration(seconds: 1)); // finish the animation diff --git a/packages/flutter/test/widgets/html_element_view_test.dart b/packages/flutter/test/widgets/html_element_view_test.dart index dd8866e9faafe..58961ab763368 100644 --- a/packages/flutter/test/widgets/html_element_view_test.dart +++ b/packages/flutter/test/widgets/html_element_view_test.dart @@ -15,6 +15,7 @@ import 'package:flutter/src/widgets/_html_element_view_web.dart' show debugOverridePlatformViewRegistry; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'package:web/web.dart' as web; final Object _mockHtmlElement = Object(); @@ -42,7 +43,7 @@ void main() { }); group('HtmlElementView', () { - testWidgets('Create HTML view', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Create HTML view', (WidgetTester tester) async { final int currentViewId = platformViewsRegistry.getNextPlatformViewId(); fakePlatformViewRegistry.registerViewFactory('webview', _mockViewFactory); @@ -64,7 +65,7 @@ void main() { ); }); - testWidgets('Create HTML view with PlatformViewCreatedCallback', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Create HTML view with PlatformViewCreatedCallback', (WidgetTester tester) async { final int currentViewId = platformViewsRegistry.getNextPlatformViewId(); fakePlatformViewRegistry.registerViewFactory('webview', _mockViewFactory); @@ -97,7 +98,7 @@ void main() { ); }); - testWidgets('Create HTML view with creation params', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Create HTML view with creation params', (WidgetTester tester) async { final int currentViewId = platformViewsRegistry.getNextPlatformViewId(); fakePlatformViewRegistry.registerViewFactory('webview', _mockViewFactory); await tester.pumpWidget( @@ -132,7 +133,7 @@ void main() { ); }); - testWidgets('Resize HTML view', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Resize HTML view', (WidgetTester tester) async { final int currentViewId = platformViewsRegistry.getNextPlatformViewId(); fakePlatformViewRegistry.registerViewFactory('webview', _mockViewFactory); await tester.pumpWidget( @@ -168,7 +169,7 @@ void main() { ); }); - testWidgets('Change HTML view type', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Change HTML view type', (WidgetTester tester) async { final int currentViewId = platformViewsRegistry.getNextPlatformViewId(); fakePlatformViewRegistry.registerViewFactory('webview', _mockViewFactory); fakePlatformViewRegistry.registerViewFactory('maps', _mockViewFactory); @@ -200,7 +201,7 @@ void main() { ); }); - testWidgets('Dispose HTML view', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Dispose HTML view', (WidgetTester tester) async { fakePlatformViewRegistry.registerViewFactory('webview', _mockViewFactory); await tester.pumpWidget( const Center( @@ -227,7 +228,7 @@ void main() { ); }); - testWidgets('HTML view survives widget tree change', (WidgetTester tester) async { + testWidgetsWithLeakTracking('HTML view survives widget tree change', (WidgetTester tester) async { final int currentViewId = platformViewsRegistry.getNextPlatformViewId(); fakePlatformViewRegistry.registerViewFactory('webview', _mockViewFactory); final GlobalKey key = GlobalKey(); @@ -259,7 +260,7 @@ void main() { ); }); - testWidgets('HtmlElementView has correct semantics', (WidgetTester tester) async { + testWidgetsWithLeakTracking('HtmlElementView has correct semantics', (WidgetTester tester) async { final SemanticsHandle handle = tester.ensureSemantics(); final int currentViewId = platformViewsRegistry.getNextPlatformViewId(); expect(currentViewId, greaterThanOrEqualTo(0)); @@ -306,7 +307,7 @@ void main() { debugOverridePlatformViewRegistry = null; }); - testWidgets('Create platform view from tagName', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Create platform view from tagName', (WidgetTester tester) async { final int currentViewId = platformViewsRegistry.getNextPlatformViewId(); await tester.pumpWidget( @@ -331,7 +332,7 @@ void main() { expect(htmlElement.tagName, equalsIgnoringCase('div')); }); - testWidgets('Create invisible platform view', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Create invisible platform view', (WidgetTester tester) async { final int currentViewId = platformViewsRegistry.getNextPlatformViewId(); await tester.pumpWidget( @@ -357,7 +358,7 @@ void main() { expect(htmlElement.tagName, equalsIgnoringCase('script')); }); - testWidgets('onElementCreated', (WidgetTester tester) async { + testWidgetsWithLeakTracking('onElementCreated', (WidgetTester tester) async { final List createdElements = []; void onElementCreated(Object element) { createdElements.add(element); diff --git a/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart b/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart index ef2361d50039c..729f54e9c66af 100644 --- a/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart +++ b/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart @@ -55,7 +55,7 @@ void main() { }); group('construction check', () { - testWidgets('ListWheelScrollView needs positive diameter ratio', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ListWheelScrollView needs positive diameter ratio', (WidgetTester tester) async { expect( () => ListWheelScrollView( diameterRatio: nonconst(-2.0), @@ -70,7 +70,7 @@ void main() { ); }); - testWidgets('ListWheelScrollView can have zero child', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ListWheelScrollView can have zero child', (WidgetTester tester) async { await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -83,7 +83,38 @@ void main() { expect(tester.getSize(find.byType(ListWheelScrollView)), const Size(800.0, 600.0)); }); - testWidgets('ListWheelScrollView needs positive magnification', (WidgetTester tester) async { + testWidgetsWithLeakTracking('FixedExtentScrollController onAttach, onDetach', (WidgetTester tester) async { + int attach = 0; + int detach = 0; + final FixedExtentScrollController controller = FixedExtentScrollController( + onAttach: (_) { attach++; }, + onDetach: (_) { detach++; }, + ); + addTearDown(controller.dispose); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: ListWheelScrollView( + controller: controller, + itemExtent: 50.0, + children: const [], + ), + ), + ); + await tester.pumpAndSettle(); + + expect(attach, 1); + expect(detach, 0); + + await tester.pumpWidget(Container()); + await tester.pumpAndSettle(); + + expect(attach, 1); + expect(detach, 1); + }); + + testWidgetsWithLeakTracking('ListWheelScrollView needs positive magnification', (WidgetTester tester) async { expect( () { ListWheelScrollView( @@ -97,7 +128,7 @@ void main() { ); }); - testWidgets('ListWheelScrollView needs valid overAndUnderCenterOpacity', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ListWheelScrollView needs valid overAndUnderCenterOpacity', (WidgetTester tester) async { expect( () { ListWheelScrollView( @@ -144,9 +175,9 @@ void main() { }); group('infinite scrolling', () { - testWidgets('infinite looping list', (WidgetTester tester) async { - final FixedExtentScrollController controller = - FixedExtentScrollController(); + testWidgetsWithLeakTracking('infinite looping list', (WidgetTester tester) async { + final FixedExtentScrollController controller = FixedExtentScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( @@ -190,9 +221,9 @@ void main() { ); }); - testWidgets('infinite child builder', (WidgetTester tester) async { - final FixedExtentScrollController controller = - FixedExtentScrollController(); + testWidgetsWithLeakTracking('infinite child builder', (WidgetTester tester) async { + final FixedExtentScrollController controller = FixedExtentScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( @@ -231,12 +262,12 @@ void main() { ); }); - testWidgets('child builder with lower and upper limits', (WidgetTester tester) async { + testWidgetsWithLeakTracking('child builder with lower and upper limits', (WidgetTester tester) async { // Adjust the content dimensions at the end of `RenderListWheelViewport.performLayout()` final List paintedChildren = []; - final FixedExtentScrollController controller = - FixedExtentScrollController(initialItem: -10); + final FixedExtentScrollController controller = FixedExtentScrollController(initialItem: -10); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( @@ -289,9 +320,11 @@ void main() { }); group('layout', () { - testWidgets('Flings with high velocity should not break the children lower and upper limits', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Flings with high velocity should not break the children lower and upper limits', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/112526 final FixedExtentScrollController controller = FixedExtentScrollController(); + addTearDown(controller.dispose); + Widget buildFrame() { return Directionality( textDirection: TextDirection.ltr, @@ -328,8 +361,10 @@ void main() { }, variant: TargetPlatformVariant(TargetPlatform.values.toSet())); // Regression test for https://github.com/flutter/flutter/issues/90953 - testWidgets('ListWheelScrollView childDelegate update test 2', (WidgetTester tester) async { - final FixedExtentScrollController controller = FixedExtentScrollController( initialItem: 2 ); + testWidgetsWithLeakTracking('ListWheelScrollView childDelegate update test 2', (WidgetTester tester) async { + final FixedExtentScrollController controller = FixedExtentScrollController(initialItem: 2); + addTearDown(controller.dispose); + Widget buildFrame(int childCount) { return Directionality( textDirection: TextDirection.ltr, @@ -391,8 +426,10 @@ void main() { }); // Regression test for https://github.com/flutter/flutter/issues/58144 - testWidgets('ListWheelScrollView childDelegate update test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ListWheelScrollView childDelegate update test', (WidgetTester tester) async { final FixedExtentScrollController controller = FixedExtentScrollController(); + addTearDown(controller.dispose); + Widget buildFrame(int childCount) { return Directionality( textDirection: TextDirection.ltr, @@ -422,7 +459,7 @@ void main() { expect(tester.renderObject(find.text('1')).attached, true); }); - testWidgets("ListWheelScrollView takes parent's size with small children", (WidgetTester tester) async { + testWidgetsWithLeakTracking("ListWheelScrollView takes parent's size with small children", (WidgetTester tester) async { await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -443,7 +480,7 @@ void main() { expect(tester.getBottomRight(find.byType(ListWheelScrollView)), const Offset(800.0, 600.0)); }); - testWidgets("ListWheelScrollView takes parent's size with large children", (WidgetTester tester) async { + testWidgetsWithLeakTracking("ListWheelScrollView takes parent's size with large children", (WidgetTester tester) async { await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -464,7 +501,7 @@ void main() { expect(tester.getBottomRight(find.byType(ListWheelScrollView)), const Offset(800.0, 600.0)); }); - testWidgets("ListWheelScrollView children can't be bigger than itemExtent", (WidgetTester tester) async { + testWidgetsWithLeakTracking("ListWheelScrollView children can't be bigger than itemExtent", (WidgetTester tester) async { await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -486,10 +523,10 @@ void main() { expect(find.text('blah'), findsOneWidget); }); - testWidgets('builder is never called twice for same index', (WidgetTester tester) async { + testWidgetsWithLeakTracking('builder is never called twice for same index', (WidgetTester tester) async { final Set builtChildren = {}; - final FixedExtentScrollController controller = - FixedExtentScrollController(); + final FixedExtentScrollController controller = FixedExtentScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( @@ -523,9 +560,9 @@ void main() { await tester.pump(); }); - testWidgets('only visible children are maintained as children of the rendered viewport', (WidgetTester tester) async { - final FixedExtentScrollController controller = - FixedExtentScrollController(); + testWidgetsWithLeakTracking('only visible children are maintained as children of the rendered viewport', (WidgetTester tester) async { + final FixedExtentScrollController controller = FixedExtentScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( @@ -560,9 +597,9 @@ void main() { expect(viewport.childCount, 4); }); - testWidgets('a tighter squeeze lays out more children', (WidgetTester tester) async { - final FixedExtentScrollController controller = - FixedExtentScrollController(initialItem: 10); + testWidgetsWithLeakTracking('a tighter squeeze lays out more children', (WidgetTester tester) async { + final FixedExtentScrollController controller = FixedExtentScrollController(initialItem: 10); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( @@ -605,7 +642,7 @@ void main() { expect(viewport.childCount, 13); }); - testWidgets('Active children are laid out with correct offset', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Active children are laid out with correct offset', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/123497 Future buildWidget(double width) async { return tester.pumpWidget( @@ -642,8 +679,9 @@ void main() { }); group('pre-transform viewport', () { - testWidgets('ListWheelScrollView starts and ends from the middle', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ListWheelScrollView starts and ends from the middle', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); final List paintedChildren = []; await tester.pumpWidget( @@ -684,8 +722,9 @@ void main() { expect(paintedChildren, [96, 97, 98, 99]); }); - testWidgets('A child gets painted as soon as its first pixel is in the viewport', (WidgetTester tester) async { + testWidgetsWithLeakTracking('A child gets painted as soon as its first pixel is in the viewport', (WidgetTester tester) async { final ScrollController controller = ScrollController(initialScrollOffset: 50.0); + addTearDown(controller.dispose); final List paintedChildren = []; await tester.pumpWidget( @@ -718,8 +757,9 @@ void main() { expect(paintedChildren, [0, 1, 2, 3, 4]); }); - testWidgets('A child is no longer painted after its last pixel leaves the viewport', (WidgetTester tester) async { + testWidgetsWithLeakTracking('A child is no longer painted after its last pixel leaves the viewport', (WidgetTester tester) async { final ScrollController controller = ScrollController(initialScrollOffset: 250.0); + addTearDown(controller.dispose); final List paintedChildren = []; await tester.pumpWidget( @@ -762,7 +802,7 @@ void main() { }); group('viewport transformation', () { - testWidgets('Center child is magnified', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Center child is magnified', (WidgetTester tester) async { await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -786,7 +826,7 @@ void main() { ); }); - testWidgets('Default middle transform', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Default middle transform', (WidgetTester tester) async { await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -815,8 +855,10 @@ void main() { )); }); - testWidgets('Curve the wheel to the left', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Curve the wheel to the left', (WidgetTester tester) async { final ScrollController controller = ScrollController(initialScrollOffset: 300.0); + addTearDown(controller.dispose); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -840,8 +882,9 @@ void main() { ); }); - testWidgets('Scrolling, diameterRatio, perspective all changes matrix', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Scrolling, diameterRatio, perspective all changes matrix', (WidgetTester tester) async { final ScrollController controller = ScrollController(initialScrollOffset: 200.0); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( @@ -959,8 +1002,9 @@ void main() { )); }); - testWidgets('offAxisFraction, magnification changes matrix', (WidgetTester tester) async { + testWidgetsWithLeakTracking('offAxisFraction, magnification changes matrix', (WidgetTester tester) async { final ScrollController controller = ScrollController(initialScrollOffset: 200.0); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( @@ -1058,7 +1102,7 @@ void main() { }); group('scroll notifications', () { - testWidgets('no onSelectedItemChanged callback on first build', (WidgetTester tester) async { + testWidgetsWithLeakTracking('no onSelectedItemChanged callback on first build', (WidgetTester tester) async { bool itemChangeCalled = false; void onItemChange(int _) { itemChangeCalled = true; } @@ -1083,7 +1127,7 @@ void main() { expect(itemChangeCalled, false); }); - testWidgets('onSelectedItemChanged when a new item is closest to center', (WidgetTester tester) async { + testWidgetsWithLeakTracking('onSelectedItemChanged when a new item is closest to center', (WidgetTester tester) async { final List selectedItems = []; await tester.pumpWidget( @@ -1120,7 +1164,7 @@ void main() { expect(selectedItems, [1, 2, 1]); }); - testWidgets('onSelectedItemChanged reports only in valid range', (WidgetTester tester) async { + testWidgetsWithLeakTracking('onSelectedItemChanged reports only in valid range', (WidgetTester tester) async { final List selectedItems = []; await tester.pumpWidget( @@ -1156,8 +1200,9 @@ void main() { }); group('scroll controller', () { - testWidgets('initialItem', (WidgetTester tester) async { + testWidgetsWithLeakTracking('initialItem', (WidgetTester tester) async { final FixedExtentScrollController controller = FixedExtentScrollController(initialItem: 10); + addTearDown(controller.dispose); final List paintedChildren = []; await tester.pumpWidget( @@ -1182,8 +1227,9 @@ void main() { expect(controller.selectedItem, 10); }); - testWidgets('controller jump', (WidgetTester tester) async { + testWidgetsWithLeakTracking('controller jump', (WidgetTester tester) async { final FixedExtentScrollController controller = FixedExtentScrollController(initialItem: 10); + addTearDown(controller.dispose); final List paintedChildren = []; await tester.pumpWidget( @@ -1214,8 +1260,9 @@ void main() { expect(controller.selectedItem, 0); }); - testWidgets('controller animateToItem', (WidgetTester tester) async { + testWidgetsWithLeakTracking('controller animateToItem', (WidgetTester tester) async { final FixedExtentScrollController controller = FixedExtentScrollController(initialItem: 10); + addTearDown(controller.dispose); final List paintedChildren = []; await tester.pumpWidget( @@ -1251,9 +1298,10 @@ void main() { expect(controller.selectedItem, 0); }); - testWidgets('onSelectedItemChanged and controller are in sync', (WidgetTester tester) async { + testWidgetsWithLeakTracking('onSelectedItemChanged and controller are in sync', (WidgetTester tester) async { final List selectedItems = []; final FixedExtentScrollController controller = FixedExtentScrollController(initialItem: 10); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( @@ -1303,8 +1351,7 @@ void main() { await tester.drag(find.byType(ListWheelScrollView), const Offset(0.0, -500.0)); await tester.pump(); - final FixedExtentScrollController controller1 = - FixedExtentScrollController(initialItem: 30); + final FixedExtentScrollController controller1 = FixedExtentScrollController(initialItem: 30); addTearDown(controller1.dispose); // Attaching first controller. @@ -1329,8 +1376,7 @@ void main() { expect(controller1.selectedItem, 50); expect(controller1.position.pixels, 5000.0); - final FixedExtentScrollController controller2 = - FixedExtentScrollController(initialItem: 33); + final FixedExtentScrollController controller2 = FixedExtentScrollController(initialItem: 33); addTearDown(controller2.dispose); // Attaching the second controller. @@ -1376,8 +1422,7 @@ void main() { }); testWidgetsWithLeakTracking('controller can be reused', (WidgetTester tester) async { - final FixedExtentScrollController controller = - FixedExtentScrollController(initialItem: 3); + final FixedExtentScrollController controller = FixedExtentScrollController(initialItem: 3); addTearDown(controller.dispose); await tester.pumpWidget( @@ -1427,8 +1472,9 @@ void main() { }); group('physics', () { - testWidgets('fling velocities too low snaps back to the same item', (WidgetTester tester) async { + testWidgetsWithLeakTracking('fling velocities too low snaps back to the same item', (WidgetTester tester) async { final FixedExtentScrollController controller = FixedExtentScrollController(initialItem: 40); + addTearDown(controller.dispose); final List scrolledPositions = []; await tester.pumpWidget( @@ -1477,8 +1523,9 @@ void main() { expect(scrolledPositions.last, moreOrLessEquals(40 * 1000.0, epsilon: 0.2)); }); - testWidgets('high fling velocities lands exactly on items', (WidgetTester tester) async { + testWidgetsWithLeakTracking('high fling velocities lands exactly on items', (WidgetTester tester) async { final FixedExtentScrollController controller = FixedExtentScrollController(initialItem: 40); + addTearDown(controller.dispose); final List scrolledPositions = []; await tester.pumpWidget( @@ -1530,9 +1577,11 @@ void main() { }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); }); - testWidgets('ListWheelScrollView getOffsetToReveal', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ListWheelScrollView getOffsetToReveal', (WidgetTester tester) async { List outerChildren; final List innerChildren = List.generate(10, (int index) => Container()); + final ScrollController controller = ScrollController(initialScrollOffset: 300.0); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( @@ -1542,7 +1591,7 @@ void main() { height: 500.0, width: 300.0, child: ListWheelScrollView( - controller: ScrollController(initialScrollOffset: 300.0), + controller: controller, itemExtent: 100.0, children: outerChildren = List.generate(10, (int i) { return Center( @@ -1598,10 +1647,45 @@ void main() { expect(revealed.rect, const Rect.fromLTWH(165.0, 265.0, 10.0, 10.0)); }); - testWidgets('ListWheelScrollView showOnScreen', (WidgetTester tester) async { + testWidgetsWithLeakTracking('will not assert on getOffsetToReveal Axis', (WidgetTester tester) async { + final ScrollController controller = ScrollController(initialScrollOffset: 300.0); + addTearDown(controller.dispose); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + height: 500.0, + width: 300.0, + child: ListWheelScrollView( + controller: controller, + itemExtent: 100.0, + children: List.generate(10, (int i) { + return Center( + child: SizedBox( + height: 50.0, + width: 50.0, + child: Text('Item $i'), + ), + ); + }), + ), + ), + ), + ), + ); + + final RenderListWheelViewport viewport = tester.allRenderObjects.whereType().first; + final RenderObject target = tester.renderObject(find.text('Item 5')); + viewport.getOffsetToReveal(target, 0.0, axis: Axis.horizontal); + }); + + testWidgetsWithLeakTracking('ListWheelScrollView showOnScreen', (WidgetTester tester) async { List outerChildren; final List innerChildren = List.generate(10, (int index) => Container()); - ScrollController controller; + final ScrollController controller = ScrollController(initialScrollOffset: 300.0); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( @@ -1611,7 +1695,7 @@ void main() { height: 500.0, width: 300.0, child: ListWheelScrollView( - controller: controller = ScrollController(initialScrollOffset: 300.0), + controller: controller, itemExtent: 100.0, children: outerChildren = List.generate(10, (int i) { @@ -1654,8 +1738,9 @@ void main() { }); group('gestures', () { - testWidgets('ListWheelScrollView allows taps for on its children', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ListWheelScrollView allows taps for on its children', (WidgetTester tester) async { final FixedExtentScrollController controller = FixedExtentScrollController(initialItem: 10); + addTearDown(controller.dispose); final List children = List.generate(100, (int index) => index); final List paintedChildren = []; final Set tappedChildren = {}; @@ -1696,8 +1781,9 @@ void main() { expect(tappedChildren, paintedChildren); }); - testWidgets('ListWheelScrollView allows for horizontal drags on its children', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ListWheelScrollView allows for horizontal drags on its children', (WidgetTester tester) async { final PageController pageController = PageController(); + addTearDown(pageController.dispose); await tester.pumpWidget( Directionality( @@ -1723,10 +1809,11 @@ void main() { expect(pageController.page, 1.0); }); - testWidgets('ListWheelScrollView does not crash and does not allow taps on children that were laid out, but not painted', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ListWheelScrollView does not crash and does not allow taps on children that were laid out, but not painted', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/126491 final FixedExtentScrollController controller = FixedExtentScrollController(); + addTearDown(controller.dispose); final List children = List.generate(100, (int index) => index); final List paintedChildren = []; final Set tappedChildren = {}; @@ -1783,7 +1870,7 @@ void main() { }); }); - testWidgets('ListWheelScrollView creates only one opacity layer for all children', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ListWheelScrollView creates only one opacity layer for all children', (WidgetTester tester) async { await tester.pumpWidget( ListWheelScrollView( overAndUnderCenterOpacity: 0.5, diff --git a/packages/flutter/test/widgets/navigator_test.dart b/packages/flutter/test/widgets/navigator_test.dart index 8044583a7b276..9b28b0923afa9 100644 --- a/packages/flutter/test/widgets/navigator_test.dart +++ b/packages/flutter/test/widgets/navigator_test.dart @@ -121,7 +121,7 @@ class SlideInOutPageRoute extends PageRouteBuilder { } void main() { - testWidgets('Can navigator navigate to and from a stateful widget', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can navigator navigate to and from a stateful widget', (WidgetTester tester) async { final Map routes = { '/': (BuildContext context) => const FirstWidget(), // X '/second': (BuildContext context) => const SecondWidget(), // Y @@ -171,7 +171,7 @@ void main() { expect(find.text('Y', skipOffstage: false), findsNothing); }); - testWidgets('Navigator.of fails gracefully when not found in context', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Navigator.of fails gracefully when not found in context', (WidgetTester tester) async { const Key targetKey = Key('foo'); dynamic exception; final Widget widget = ThirdWidget( @@ -186,7 +186,7 @@ void main() { expect('$exception', startsWith('Navigator operation requested with a context')); }); - testWidgets('Navigator can push Route created through page class as Pageless route', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Navigator can push Route created through page class as Pageless route', (WidgetTester tester) async { final GlobalKey nav = GlobalKey(); await tester.pumpWidget( MaterialApp( @@ -206,7 +206,7 @@ void main() { expect(find.text('home'), findsOneWidget); }); - testWidgets('Navigator can set clip behavior', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Navigator can set clip behavior', (WidgetTester tester) async { const MaterialPage page = MaterialPage(child: Text('page')); await tester.pumpWidget( MediaQuery( @@ -239,7 +239,7 @@ void main() { expect(tester.widget(find.byType(Overlay)).clipBehavior, Clip.none); }); - testWidgets('Zero transition page-based route correctly notifies observers when it is popped', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Zero transition page-based route correctly notifies observers when it is popped', (WidgetTester tester) async { final List> pages = >[ const ZeroTransitionPage(name: 'Page 1'), const ZeroTransitionPage(name: 'Page 2'), @@ -279,7 +279,7 @@ void main() { expect(observations[0].previous, 'Page 1'); }); - testWidgets('Navigator.of rootNavigator finds root Navigator', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Navigator.of rootNavigator finds root Navigator', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp( home: Material( child: Column( @@ -347,7 +347,7 @@ void main() { expect(tester.getTopLeft(find.text('Dialog')).dy, 0.0); }); - testWidgets('Gestures between push and build are ignored', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Gestures between push and build are ignored', (WidgetTester tester) async { final List log = []; final Map routes = { '/': (BuildContext context) { @@ -377,7 +377,7 @@ void main() { expect(log, equals(['left'])); }); - testWidgets('pushnamed can handle Object as type', (WidgetTester tester) async { + testWidgetsWithLeakTracking('pushnamed can handle Object as type', (WidgetTester tester) async { final GlobalKey nav = GlobalKey(); final Map routes = { '/': (BuildContext context) => const Text('/'), @@ -397,7 +397,7 @@ void main() { expect(find.text('/second'), findsOneWidget); }); - testWidgets('Pending gestures are rejected', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Pending gestures are rejected', (WidgetTester tester) async { final List log = []; final Map routes = { '/': (BuildContext context) { @@ -428,7 +428,7 @@ void main() { expect(log, equals(['left'])); }); - testWidgets('popAndPushNamed', (WidgetTester tester) async { + testWidgetsWithLeakTracking('popAndPushNamed', (WidgetTester tester) async { final Map routes = { '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }), '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.popAndPushNamed(context, '/B'); }), @@ -455,7 +455,7 @@ void main() { expect(find.text('B'), findsOneWidget); }); - testWidgets('popAndPushNamed with explicit void type parameter', (WidgetTester tester) async { + testWidgetsWithLeakTracking('popAndPushNamed with explicit void type parameter', (WidgetTester tester) async { final Map routes = { '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }), '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.popAndPushNamed(context, '/B'); }), @@ -482,7 +482,7 @@ void main() { expect(find.text('B'), findsOneWidget); }); - testWidgets('Push and pop should trigger the observers', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Push and pop should trigger the observers', (WidgetTester tester) async { final Map routes = { '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }), '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context); }), @@ -542,7 +542,7 @@ void main() { expect(isPopped, isTrue); }); - testWidgets('Add and remove an observer should work', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Add and remove an observer should work', (WidgetTester tester) async { final Map routes = { '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }), '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context); }), @@ -589,7 +589,7 @@ void main() { expect(isPopped, isFalse); }); - testWidgets('initial route trigger observer in the right order', (WidgetTester tester) async { + testWidgetsWithLeakTracking('initial route trigger observer in the right order', (WidgetTester tester) async { final Map routes = { '/' : (BuildContext context) => const Text('/'), '/A': (BuildContext context) => const Text('A'), @@ -663,7 +663,7 @@ void main() { MemoryAllocations.instance.removeListener(listener); }); - testWidgets('Route didAdd and dispose in same frame work', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Route didAdd and dispose in same frame work', (WidgetTester tester) async { // Regression Test for https://github.com/flutter/flutter/issues/61346. Widget buildNavigator() { return Navigator( @@ -676,6 +676,8 @@ void main() { ); } final TabController controller = TabController(length: 3, vsync: tester); + addTearDown(controller.dispose); + await tester.pumpWidget( TestDependencies( child: TabBarView( @@ -694,7 +696,7 @@ void main() { await tester.pumpAndSettle(); }); - testWidgets('Page-based route pop before push finishes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Page-based route pop before push finishes', (WidgetTester tester) async { List> pages = >[const MaterialPage(child: Text('Page 1'))]; final GlobalKey navigator = GlobalKey(); Widget buildNavigator() { @@ -730,7 +732,7 @@ void main() { expect(find.text('Page 1'), findsOneWidget); }); - testWidgets('Pages update does update overlay correctly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Pages update does update overlay correctly', (WidgetTester tester) async { // Regression Test for https://github.com/flutter/flutter/issues/64941. List> pages = const >[ MaterialPage( @@ -779,7 +781,7 @@ void main() { expect(find.text('page 0'), findsNothing); }); - testWidgets('replaceNamed replaces', (WidgetTester tester) async { + testWidgetsWithLeakTracking('replaceNamed replaces', (WidgetTester tester) async { final Map routes = { '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushReplacementNamed(context, '/A'); }), '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pushReplacementNamed(context, '/B'); }), @@ -801,7 +803,7 @@ void main() { expect(find.text('B'), findsOneWidget); }); - testWidgets('pushReplacement sets secondaryAnimation after transition, with history change during transition', (WidgetTester tester) async { + testWidgetsWithLeakTracking('pushReplacement sets secondaryAnimation after transition, with history change during transition', (WidgetTester tester) async { final Map> routes = >{}; final Map builders = { '/' : (BuildContext context) => OnTapPage( @@ -858,7 +860,7 @@ void main() { expect(routes['/A']!.secondaryAnimation!.value, equals(routes['/C']!.animation!.value)); }); - testWidgets('new route removed from navigator history during pushReplacement transition', (WidgetTester tester) async { + testWidgetsWithLeakTracking('new route removed from navigator history during pushReplacement transition', (WidgetTester tester) async { final Map> routes = >{}; final Map builders = { '/' : (BuildContext context) => OnTapPage( @@ -904,7 +906,7 @@ void main() { expect(routes['/']!.animation!.value, equals(1.0)); }); - testWidgets('pushReplacement triggers secondaryAnimation', (WidgetTester tester) async { + testWidgetsWithLeakTracking('pushReplacement triggers secondaryAnimation', (WidgetTester tester) async { final Map routes = { '/' : (BuildContext context) => OnTapPage( id: '/', @@ -953,7 +955,7 @@ void main() { expect(aOffset.dx, lessThan(aOffsetOriginal.dx)); }); - testWidgets('pushReplacement correctly reports didReplace to the observer', (WidgetTester tester) async { + testWidgetsWithLeakTracking('pushReplacement correctly reports didReplace to the observer', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/56892. final Map routes = { '/' : (BuildContext context) => const OnTapPage( @@ -1021,7 +1023,7 @@ void main() { expect(find.text('C'), isOnstage); }); - testWidgets('Able to pop all routes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Able to pop all routes', (WidgetTester tester) async { final Map routes = { '/' : (BuildContext context) => const OnTapPage( id: '/', @@ -1048,7 +1050,7 @@ void main() { expect(tester.takeException(), isNull); }); - testWidgets('pushAndRemoveUntil triggers secondaryAnimation', (WidgetTester tester) async { + testWidgetsWithLeakTracking('pushAndRemoveUntil triggers secondaryAnimation', (WidgetTester tester) async { final Map routes = { '/' : (BuildContext context) => OnTapPage( id: '/', @@ -1102,7 +1104,7 @@ void main() { expect(find.text('B'), isOnstage); }); - testWidgets('pushAndRemoveUntil does not remove routes below the first route that pass the predicate', (WidgetTester tester) async { + testWidgetsWithLeakTracking('pushAndRemoveUntil does not remove routes below the first route that pass the predicate', (WidgetTester tester) async { // Regression https://github.com/flutter/flutter/issues/56688 final GlobalKey navigator = GlobalKey(); final Map routes = { @@ -1138,7 +1140,7 @@ void main() { expect(find.text('home'), isOnstage); }); - testWidgets('replaceNamed returned value', (WidgetTester tester) async { + testWidgetsWithLeakTracking('replaceNamed returned value', (WidgetTester tester) async { late Future value; final Map routes = { @@ -1187,7 +1189,7 @@ void main() { expect(replaceNamedValue, 'B'); }); - testWidgets('removeRoute', (WidgetTester tester) async { + testWidgetsWithLeakTracking('removeRoute', (WidgetTester tester) async { final Map pageBuilders = { '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }), '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pushNamed(context, '/B'); }), @@ -1273,7 +1275,7 @@ void main() { expect(previousRoute, routes['/']); }); - testWidgets('remove a route whose value is awaited', (WidgetTester tester) async { + testWidgetsWithLeakTracking('remove a route whose value is awaited', (WidgetTester tester) async { late Future pageValue; final Map pageBuilders = { '/': (BuildContext context) => OnTapPage(id: '/', onTap: () { pageValue = Navigator.pushNamed(context, '/A'); }), @@ -1301,7 +1303,7 @@ void main() { navigator.removeRoute(routes['/A']!); // stack becomes /, pageValue will not complete }); - testWidgets('replacing route can be observed', (WidgetTester tester) async { + testWidgetsWithLeakTracking('replacing route can be observed', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final List log = []; final TestObserver observer = TestObserver() @@ -1371,7 +1373,7 @@ void main() { expect(log, ['pushed / (previous is )', 'pushed B (previous is /)', 'pushed C (previous is B)', 'replaced B with D']); }); - testWidgets('didStartUserGesture observable', (WidgetTester tester) async { + testWidgetsWithLeakTracking('didStartUserGesture observable', (WidgetTester tester) async { final Map routes = { '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }), '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context); }), @@ -1402,7 +1404,7 @@ void main() { expect(observedPreviousRoute.settings.name, '/'); }); - testWidgets('ModalRoute.of sets up a route to rebuild if its state changes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ModalRoute.of sets up a route to rebuild if its state changes', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final List log = []; late Route routeB; @@ -1469,7 +1471,7 @@ void main() { expect(log, ['building B', 'building C', 'found C', 'building D']); }); - testWidgets("Routes don't rebuild just because their animations ended", (WidgetTester tester) async { + testWidgetsWithLeakTracking("Routes don't rebuild just because their animations ended", (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final List log = []; Route? nextRoute = PageRouteBuilder( @@ -1512,7 +1514,7 @@ void main() { expect(log, ['building page 1 - false', 'building page 2 - false', 'building page 3 - false']); }); - testWidgets('route semantics', (WidgetTester tester) async { + testWidgetsWithLeakTracking('route semantics', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); final Map routes = { '/': (BuildContext context) => OnTapPage(id: '1', onTap: () { Navigator.pushNamed(context, '/A'); }), @@ -1569,7 +1571,7 @@ void main() { semantics.dispose(); }); - testWidgets('arguments for named routes on Navigator', (WidgetTester tester) async { + testWidgetsWithLeakTracking('arguments for named routes on Navigator', (WidgetTester tester) async { late GlobalKey currentRouteKey; final List arguments = []; @@ -1643,7 +1645,7 @@ void main() { arguments.clear(); }); - testWidgets('arguments for named routes on NavigatorState', (WidgetTester tester) async { + testWidgetsWithLeakTracking('arguments for named routes on NavigatorState', (WidgetTester tester) async { final GlobalKey navigatorKey = GlobalKey(); final List arguments = []; @@ -1714,7 +1716,7 @@ void main() { arguments.clear(); }); - testWidgets('Initial route can have gaps', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Initial route can have gaps', (WidgetTester tester) async { final GlobalKey keyNav = GlobalKey(); const Key keyRoot = Key('Root'); const Key keyA = Key('A'); @@ -1745,7 +1747,7 @@ void main() { expect(find.byKey(keyABC, skipOffstage: false), findsNothing); }); - testWidgets('The full initial route has to be matched', (WidgetTester tester) async { + testWidgetsWithLeakTracking('The full initial route has to be matched', (WidgetTester tester) async { final GlobalKey keyNav = GlobalKey(); const Key keyRoot = Key('Root'); const Key keyA = Key('A'); @@ -1775,7 +1777,7 @@ void main() { expect(find.byKey(keyAB), findsNothing); }); - testWidgets("Popping immediately after pushing doesn't crash", (WidgetTester tester) async { + testWidgetsWithLeakTracking("Popping immediately after pushing doesn't crash", (WidgetTester tester) async { // Added this test to protect against regression of https://github.com/flutter/flutter/issues/45539 final Map routes = { '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { @@ -1824,7 +1826,7 @@ void main() { }); group('error control test', () { - testWidgets('onUnknownRoute null and onGenerateRoute returns null', (WidgetTester tester) async { + testWidgetsWithLeakTracking('onUnknownRoute null and onGenerateRoute returns null', (WidgetTester tester) async { final GlobalKey navigatorKey = GlobalKey(); await tester.pumpWidget(Navigator( key: navigatorKey, @@ -1850,7 +1852,7 @@ void main() { ); }); - testWidgets('onUnknownRoute null and onGenerateRoute returns null', (WidgetTester tester) async { + testWidgetsWithLeakTracking('onUnknownRoute null and onGenerateRoute returns null', (WidgetTester tester) async { final GlobalKey navigatorKey = GlobalKey(); await tester.pumpWidget(Navigator( key: navigatorKey, @@ -1877,7 +1879,7 @@ void main() { }); }); - testWidgets('OverlayEntry of topmost initial route is marked as opaque', (WidgetTester tester) async { + testWidgetsWithLeakTracking('OverlayEntry of topmost initial route is marked as opaque', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/38038. final Key root = UniqueKey(); @@ -1901,7 +1903,7 @@ void main() { expect(find.byKey(topmost), findsOneWidget); }); - testWidgets('OverlayEntry of topmost route is set to opaque after Push', (WidgetTester tester) async { + testWidgetsWithLeakTracking('OverlayEntry of topmost route is set to opaque after Push', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/38038. final GlobalKey navigator = GlobalKey(); @@ -1928,7 +1930,7 @@ void main() { expect(find.byKey(const ValueKey('/A')), findsOneWidget); }); - testWidgets('OverlayEntry of topmost route is set to opaque after Replace', (WidgetTester tester) async { + testWidgetsWithLeakTracking('OverlayEntry of topmost route is set to opaque after Replace', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/38038. final GlobalKey navigator = GlobalKey(); @@ -1973,7 +1975,7 @@ void main() { expect(find.byKey(const ValueKey('/C')), findsOneWidget); }); - testWidgets('Pushing opaque Route does not rebuild routes below', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Pushing opaque Route does not rebuild routes below', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/45797. final GlobalKey navigator = GlobalKey(); @@ -2007,7 +2009,7 @@ void main() { expect(tester.state(find.byKey(topRoute)).rebuildCount, 1); }); - testWidgets('initial routes below opaque route are offstage', (WidgetTester tester) async { + testWidgetsWithLeakTracking('initial routes below opaque route are offstage', (WidgetTester tester) async { final GlobalKey testKey = GlobalKey(); await tester.pumpWidget( TestDependencies( @@ -2048,7 +2050,7 @@ void main() { expect(find.text('+/a/b+'), findsNothing); }); - testWidgets('Can provide custom onGenerateInitialRoutes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can provide custom onGenerateInitialRoutes', (WidgetTester tester) async { bool onGenerateInitialRoutesCalled = false; final GlobalKey testKey = GlobalKey(); await tester.pumpWidget( @@ -2081,7 +2083,7 @@ void main() { expect(find.text('World'), findsNothing); }); - testWidgets('Navigator.of able to handle input context is a navigator context', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Navigator.of able to handle input context is a navigator context', (WidgetTester tester) async { final GlobalKey testKey = GlobalKey(); await tester.pumpWidget( MaterialApp( @@ -2094,7 +2096,7 @@ void main() { expect(state, testKey.currentState); }); - testWidgets('Navigator.of able to handle input context is a navigator context - root navigator', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Navigator.of able to handle input context is a navigator context - root navigator', (WidgetTester tester) async { final GlobalKey root = GlobalKey(); final GlobalKey sub = GlobalKey(); await tester.pumpWidget( @@ -2116,7 +2118,7 @@ void main() { expect(state, root.currentState); }); - testWidgets('Navigator.maybeOf throws when there is no navigator', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Navigator.maybeOf throws when there is no navigator', (WidgetTester tester) async { final GlobalKey testKey = GlobalKey(); await tester.pumpWidget(SizedBox(key: testKey)); @@ -2125,7 +2127,7 @@ void main() { }, throwsFlutterError); }); - testWidgets('Navigator.maybeOf works when there is no navigator', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Navigator.maybeOf works when there is no navigator', (WidgetTester tester) async { final GlobalKey testKey = GlobalKey(); await tester.pumpWidget(SizedBox(key: testKey)); @@ -2133,7 +2135,7 @@ void main() { expect(state, isNull); }); - testWidgets('Navigator.maybeOf able to handle input context is a navigator context', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Navigator.maybeOf able to handle input context is a navigator context', (WidgetTester tester) async { final GlobalKey testKey = GlobalKey(); await tester.pumpWidget( MaterialApp( @@ -2147,7 +2149,7 @@ void main() { expect(state, testKey.currentState); }); - testWidgets('Navigator.maybeOf able to handle input context is a navigator context - root navigator', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Navigator.maybeOf able to handle input context is a navigator context - root navigator', (WidgetTester tester) async { final GlobalKey root = GlobalKey(); final GlobalKey sub = GlobalKey(); await tester.pumpWidget( @@ -2170,7 +2172,7 @@ void main() { expect(state, root.currentState); }); - testWidgets('pushAndRemove until animates the push', (WidgetTester tester) async { + testWidgetsWithLeakTracking('pushAndRemove until animates the push', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/25080. const Duration kFourTenthsOfTheTransitionDuration = Duration(milliseconds: 120); @@ -2252,7 +2254,7 @@ void main() { expect(find.text('Route: 4', skipOffstage: false), findsNothing); }); - testWidgets('Wrapping TickerMode can turn off ticking in routes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Wrapping TickerMode can turn off ticking in routes', (WidgetTester tester) async { int tickCount = 0; Widget widgetUnderTest({required bool enabled}) { return TickerMode( @@ -2345,7 +2347,7 @@ void main() { expect(popNextOfFirst, secondRoute); }); - testWidgets('hero controller scope works', (WidgetTester tester) async { + testWidgetsWithLeakTracking('hero controller scope works', (WidgetTester tester) async { final GlobalKey top = GlobalKey(); final GlobalKey sub = GlobalKey(); @@ -2415,7 +2417,7 @@ void main() { expect(observations[1].previous, 'top1'); }); - testWidgets('hero controller can correctly transfer subscription - replacing navigator', (WidgetTester tester) async { + testWidgetsWithLeakTracking('hero controller can correctly transfer subscription - replacing navigator', (WidgetTester tester) async { final GlobalKey key1 = GlobalKey(); final GlobalKey key2 = GlobalKey(); @@ -2484,7 +2486,7 @@ void main() { expect(observations[0].previous, 'navigator2'); }); - testWidgets('hero controller can correctly transfer subscription - swapping navigator', (WidgetTester tester) async { + testWidgetsWithLeakTracking('hero controller can correctly transfer subscription - swapping navigator', (WidgetTester tester) async { final GlobalKey key1 = GlobalKey(); final GlobalKey key2 = GlobalKey(); @@ -2624,7 +2626,7 @@ void main() { expect(observations2[1].previous, 'navigator1'); }); - testWidgets('hero controller subscribes to multiple navigators does throw', (WidgetTester tester) async { + testWidgetsWithLeakTracking('hero controller subscribes to multiple navigators does throw', (WidgetTester tester) async { final HeroControllerSpy spy = HeroControllerSpy(); await tester.pumpWidget( HeroControllerScope( @@ -2662,7 +2664,7 @@ void main() { expect(tester.takeException(), isAssertionError); }); - testWidgets('hero controller throws has correct error message', (WidgetTester tester) async { + testWidgetsWithLeakTracking('hero controller throws has correct error message', (WidgetTester tester) async { final HeroControllerSpy spy = HeroControllerSpy(); await tester.pumpWidget( HeroControllerScope( @@ -2746,7 +2748,7 @@ void main() { ); } - testWidgets('can initialize with pages list', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can initialize with pages list', (WidgetTester tester) async { final GlobalKey navigator = GlobalKey(); final List myPages = [ const TestPage(key: ValueKey('1'), name:'initial'), @@ -2784,7 +2786,7 @@ void main() { expect(find.text('initial'), findsOneWidget); }); - testWidgets('can handle duplicate page key if update before transition finishes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can handle duplicate page key if update before transition finishes', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/97363. final GlobalKey navigator = GlobalKey(); final List myPages1 = [ @@ -2840,7 +2842,7 @@ void main() { expect(tester.takeException(), isNull); }); - testWidgets('throw if onPopPage callback is not provided', (WidgetTester tester) async { + testWidgetsWithLeakTracking('throw if onPopPage callback is not provided', (WidgetTester tester) async { final List myPages = [ const TestPage(key: ValueKey('1'), name:'initial'), const TestPage(key: ValueKey('2'), name:'second'), @@ -2910,7 +2912,7 @@ void main() { ); }); - testWidgets('Can pop route with local history entries using page api', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can pop route with local history entries using page api', (WidgetTester tester) async { List> myPages = const >[ MaterialPage(child: Text('page1')), MaterialPage(child: Text('page2')), @@ -2961,7 +2963,7 @@ void main() { expect(entryRemoved, isTrue); }); - testWidgets('ModalRoute must comply with willHandlePopInternally when there is a PopScope', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ModalRoute must comply with willHandlePopInternally when there is a PopScope', (WidgetTester tester) async { const List> myPages = >[ MaterialPage(child: Text('page1')), MaterialPage( @@ -2994,7 +2996,7 @@ void main() { expect(route.didPop(null), true); }); - testWidgets('can push and pop pages using page api', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can push and pop pages using page api', (WidgetTester tester) async { late Animation secondaryAnimationOfRouteOne; late Animation primaryAnimationOfRouteOne; late Animation secondaryAnimationOfRouteTwo; @@ -3143,7 +3145,7 @@ void main() { expect(primaryAnimationOfRouteThree.status, AnimationStatus.dismissed); }); - testWidgets('can modify routes history and secondary animation still works', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can modify routes history and secondary animation still works', (WidgetTester tester) async { final GlobalKey navigator = GlobalKey(); late Animation secondaryAnimationOfRouteOne; late Animation primaryAnimationOfRouteOne; @@ -3254,7 +3256,7 @@ void main() { expect(primaryAnimationOfRouteOne.status, AnimationStatus.dismissed); }); - testWidgets('Pop no animation page does not crash', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Pop no animation page does not crash', (WidgetTester tester) async { // Regression Test for https://github.com/flutter/flutter/issues/86604. Widget buildNavigator(bool secondPage) { return TestDependencies( @@ -3279,7 +3281,7 @@ void main() { expect(find.text('page1'), findsOneWidget); }); - testWidgets('can work with pageless route', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can work with pageless route', (WidgetTester tester) async { final GlobalKey navigator = GlobalKey(); List myPages = [ const TestPage(key: ValueKey('1'), name:'initial'), @@ -3427,7 +3429,7 @@ void main() { expect(myPages.length, 1); }); - testWidgets('complex case 1', (WidgetTester tester) async { + testWidgetsWithLeakTracking('complex case 1', (WidgetTester tester) async { final GlobalKey navigator = GlobalKey(); List myPages = [ const TestPage(key: ValueKey('1'), name: 'initial'), @@ -3564,7 +3566,7 @@ void main() { }); //Regression test for https://github.com/flutter/flutter/issues/115887 - testWidgets('Complex case 2', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Complex case 2', (WidgetTester tester) async { final GlobalKey navigator = GlobalKey(); List myPages = [ const TestPage(key: ValueKey('1'), name:'initial'), @@ -3628,7 +3630,7 @@ void main() { expect(find.text('second-pageless1'), findsNothing); }); - testWidgets('complex case 1 - with always remove transition delegate', (WidgetTester tester) async { + testWidgetsWithLeakTracking('complex case 1 - with always remove transition delegate', (WidgetTester tester) async { final GlobalKey navigator = GlobalKey(); final AlwaysRemoveTransitionDelegate transitionDelegate = AlwaysRemoveTransitionDelegate(); List myPages = [ @@ -3773,7 +3775,7 @@ void main() { expect(find.text('forth'), findsOneWidget); }); - testWidgets('can repush a page that was previously popped before it has finished popping', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can repush a page that was previously popped before it has finished popping', (WidgetTester tester) async { final GlobalKey navigator = GlobalKey(); List> myPages = [ const TestPage(key: ValueKey('1'), name: 'initial'), @@ -3825,7 +3827,7 @@ void main() { expect(find.text('second'), findsOneWidget); }); - testWidgets('can update pages before a route has finished popping', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can update pages before a route has finished popping', (WidgetTester tester) async { final GlobalKey navigator = GlobalKey(); List> myPages = [ const TestPage(key: ValueKey('1'), name: 'initial'), @@ -3876,7 +3878,7 @@ void main() { expect(find.text('initial'), findsOneWidget); }); - testWidgets('can update pages before a pageless route has finished popping', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can update pages before a pageless route has finished popping', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/68162. final GlobalKey navigator = GlobalKey(); List> myPages = [ @@ -3923,7 +3925,7 @@ void main() { expect(find.text('initial'), findsOneWidget); }); - testWidgets('pages remove and add trigger observer in the right order', (WidgetTester tester) async { + testWidgetsWithLeakTracking('pages remove and add trigger observer in the right order', (WidgetTester tester) async { final GlobalKey navigator = GlobalKey(); List myPages = [ const TestPage(key: ValueKey('1'), name:'first'), @@ -4016,7 +4018,7 @@ void main() { }); }); - testWidgets('Can reuse NavigatorObserver in rebuilt tree', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can reuse NavigatorObserver in rebuilt tree', (WidgetTester tester) async { final NavigatorObserver observer = NavigatorObserver(); Widget build([Key? key]) { return TestDependencies( @@ -4051,7 +4053,7 @@ void main() { expect(observer.navigator, tester.state(find.byType(Navigator))); }); - testWidgets('Navigator requests focus if requestFocus is true', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Navigator requests focus if requestFocus is true', (WidgetTester tester) async { final GlobalKey navigatorKey = GlobalKey(); final GlobalKey innerKey = GlobalKey(); final Map routes = { @@ -4060,6 +4062,7 @@ void main() { }; late final NavigatorState navigator = navigatorKey.currentState! as NavigatorState; final FocusScopeNode focusNode = FocusScopeNode(); + addTearDown(focusNode.dispose); await tester.pumpWidget(Column( children: [ @@ -4126,7 +4129,7 @@ void main() { expect(focusNode.hasFocus, true); }); - testWidgets('Navigator does not request focus if requestFocus is false', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Navigator does not request focus if requestFocus is false', (WidgetTester tester) async { final GlobalKey navigatorKey = GlobalKey(); final GlobalKey innerKey = GlobalKey(); final Map routes = { @@ -4136,6 +4139,7 @@ void main() { late final NavigatorState navigator = navigatorKey.currentState! as NavigatorState; final FocusScopeNode focusNode = FocusScopeNode(); + addTearDown(focusNode.dispose); await tester.pumpWidget(Column( children: [ @@ -4192,7 +4196,7 @@ void main() { expect(focusNode.hasFocus, true); }); - testWidgets('class implementing NavigatorObserver can be used without problems', (WidgetTester tester) async { + testWidgetsWithLeakTracking('class implementing NavigatorObserver can be used without problems', (WidgetTester tester) async { final _MockNavigatorObserver observer = _MockNavigatorObserver(); Widget build([Key? key]) { return TestDependencies( @@ -4224,7 +4228,7 @@ void main() { observer._checkInvocations([#navigator, #navigator]); }); - testWidgets("Navigator doesn't override FocusTraversalPolicy of ancestors", (WidgetTester tester) async { + testWidgetsWithLeakTracking("Navigator doesn't override FocusTraversalPolicy of ancestors", (WidgetTester tester) async { FocusTraversalPolicy? policy; await tester.pumpWidget( TestDependencies( @@ -4247,7 +4251,7 @@ void main() { expect(policy, isA()); }); - testWidgets('Navigator inserts ReadingOrderTraversalPolicy if no ancestor has a policy', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Navigator inserts ReadingOrderTraversalPolicy if no ancestor has a policy', (WidgetTester tester) async { FocusTraversalPolicy? policy; await tester.pumpWidget( TestDependencies( @@ -4302,7 +4306,7 @@ void main() { .setMockMethodCallHandler(SystemChannels.platform, null); }); - testWidgets('a single route is already defaulted to false', (WidgetTester tester) async { + testWidgetsWithLeakTracking('a single route is already defaulted to false', (WidgetTester tester) async { await tester.pumpWidget( const MaterialApp( home: Scaffold( @@ -4317,7 +4321,7 @@ void main() { skip: isBrowser, // [intended] only non-web Android supports predictive back. ); - testWidgets('navigating around a single Navigator with .pop', (WidgetTester tester) async { + testWidgetsWithLeakTracking('navigating around a single Navigator with .pop', (WidgetTester tester) async { await tester.pumpWidget( MaterialApp( initialRoute: '/', @@ -4394,7 +4398,7 @@ void main() { skip: isBrowser, // [intended] only non-web Android supports predictive back. ); - testWidgets('navigating around a single Navigator with system back', (WidgetTester tester) async { + testWidgetsWithLeakTracking('navigating around a single Navigator with system back', (WidgetTester tester) async { await tester.pumpWidget( MaterialApp( initialRoute: '/', @@ -4471,7 +4475,7 @@ void main() { skip: isBrowser, // [intended] only non-web Android supports predictive back. ); - testWidgets('a single Navigator with a PopScope that defaults to enabled', (WidgetTester tester) async { + testWidgetsWithLeakTracking('a single Navigator with a PopScope that defaults to enabled', (WidgetTester tester) async { bool canPop = true; late StateSetter setState; await tester.pumpWidget( @@ -4511,7 +4515,7 @@ void main() { skip: isBrowser, // [intended] only non-web Android supports predictive back. ); - testWidgets('a single Navigator with a PopScope that defaults to disabled', (WidgetTester tester) async { + testWidgetsWithLeakTracking('a single Navigator with a PopScope that defaults to disabled', (WidgetTester tester) async { bool canPop = false; late StateSetter setState; await tester.pumpWidget( @@ -4553,7 +4557,7 @@ void main() { // Test both system back gestures and Navigator.pop. for (final _BackType backType in _BackType.values) { - testWidgets('navigating around nested Navigators', (WidgetTester tester) async { + testWidgetsWithLeakTracking('navigating around nested Navigators', (WidgetTester tester) async { final GlobalKey nav = GlobalKey(); final GlobalKey nestedNav = GlobalKey(); Future goBack() async { @@ -4653,7 +4657,7 @@ void main() { ); } - testWidgets('nested Navigators with a nested PopScope', (WidgetTester tester) async { + testWidgetsWithLeakTracking('nested Navigators with a nested PopScope', (WidgetTester tester) async { bool canPop = true; late StateSetter setState; await tester.pumpWidget( @@ -4780,7 +4784,7 @@ void main() { ); group('Navigator page API', () { - testWidgets('starting with one route as usual', (WidgetTester tester) async { + testWidgetsWithLeakTracking('starting with one route as usual', (WidgetTester tester) async { late StateSetter builderSetState; final List<_Page> pages = <_Page>[_Page.home]; bool canPop() => pages.length <= 1; @@ -4898,7 +4902,7 @@ void main() { skip: isBrowser, // [intended] only non-web Android supports predictive back. ); - testWidgets('starting with existing route history', (WidgetTester tester) async { + testWidgetsWithLeakTracking('starting with existing route history', (WidgetTester tester) async { final List<_Page> pages = <_Page>[_Page.home, _Page.one]; bool canPop() => pages.length <= 1; diff --git a/packages/flutter/test/widgets/overlay_test.dart b/packages/flutter/test/widgets/overlay_test.dart index 66663e061adb6..76dbf6d726d49 100644 --- a/packages/flutter/test/widgets/overlay_test.dart +++ b/packages/flutter/test/widgets/overlay_test.dart @@ -5,20 +5,26 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('OverflowEntries context contains Overlay', (WidgetTester tester) async { + testWidgetsWithLeakTracking('OverflowEntries context contains Overlay', (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); bool didBuild = false; + late final OverlayEntry overlayEntry1; + addTearDown(() => overlayEntry1..remove()..dispose()); + late final OverlayEntry overlayEntry2; + addTearDown(() => overlayEntry2..remove()..dispose()); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( key: overlayKey, initialEntries: [ - OverlayEntry( + overlayEntry1 = OverlayEntry( builder: (BuildContext context) { didBuild = true; final Overlay overlay = context.findAncestorWidgetOfExactType()!; @@ -26,7 +32,7 @@ void main() { return Container(); }, ), - OverlayEntry( + overlayEntry2 = OverlayEntry( builder: (BuildContext context) => Container(), ), ], @@ -80,25 +86,32 @@ void main() { ); }); - testWidgets('Offstage overlay', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Offstage overlay', (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); + late final OverlayEntry overlayEntry1; + addTearDown(() => overlayEntry1..remove()..dispose()); + late final OverlayEntry overlayEntry2; + addTearDown(() => overlayEntry2..remove()..dispose()); + late final OverlayEntry overlayEntry3; + addTearDown(() => overlayEntry3..remove()..dispose()); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( key: overlayKey, initialEntries: [ - OverlayEntry( + overlayEntry1 = OverlayEntry( opaque: true, maintainState: true, builder: (BuildContext context) => Container(), ), - OverlayEntry( + overlayEntry2 = OverlayEntry( opaque: true, maintainState: true, builder: (BuildContext context) => Container(), ), - OverlayEntry( + overlayEntry3 = OverlayEntry( opaque: true, maintainState: true, builder: (BuildContext context) => Container(), @@ -163,16 +176,19 @@ void main() { ); }); - testWidgets('insert top', (WidgetTester tester) async { + testWidgetsWithLeakTracking('insert top', (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); final List buildOrder = []; + late final OverlayEntry baseEntry; + addTearDown(() => baseEntry..remove()..dispose()); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( key: overlayKey, initialEntries: [ - OverlayEntry( + baseEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add('Base'); return Container(); @@ -187,8 +203,10 @@ void main() { buildOrder.clear(); final OverlayState overlay = overlayKey.currentState! as OverlayState; + late final OverlayEntry newEntry; + addTearDown(() => newEntry..remove()..dispose()); overlay.insert( - OverlayEntry( + newEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add('New'); return Container(); @@ -200,17 +218,19 @@ void main() { expect(buildOrder, ['Base', 'New']); }); - testWidgets('insert below', (WidgetTester tester) async { + testWidgetsWithLeakTracking('insert below', (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); - OverlayEntry base; + late final OverlayEntry baseEntry; + addTearDown(() => baseEntry..remove()..dispose()); final List buildOrder = []; + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( key: overlayKey, initialEntries: [ - base = OverlayEntry( + baseEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add('Base'); return Container(); @@ -225,37 +245,43 @@ void main() { buildOrder.clear(); final OverlayState overlay = overlayKey.currentState! as OverlayState; + late final OverlayEntry newEntry; + addTearDown(() => newEntry..remove()..dispose()); overlay.insert( - OverlayEntry( + newEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add('New'); return Container(); }, ), - below: base, + below: baseEntry, ); await tester.pump(); expect(buildOrder, ['New', 'Base']); }); - testWidgets('insert above', (WidgetTester tester) async { + testWidgetsWithLeakTracking('insert above', (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); - OverlayEntry base; + late final OverlayEntry baseEntry; + addTearDown(() => baseEntry..remove()..dispose()); + late final OverlayEntry topEntry; + addTearDown(() => topEntry..remove()..dispose()); final List buildOrder = []; + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( key: overlayKey, initialEntries: [ - base = OverlayEntry( + baseEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add('Base'); return Container(); }, ), - OverlayEntry( + topEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add('Top'); return Container(); @@ -270,30 +296,35 @@ void main() { buildOrder.clear(); final OverlayState overlay = overlayKey.currentState! as OverlayState; + late final OverlayEntry newEntry; + addTearDown(() => newEntry..remove()..dispose()); overlay.insert( - OverlayEntry( + newEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add('New'); return Container(); }, ), - above: base, + above: baseEntry, ); await tester.pump(); expect(buildOrder, ['Base', 'New', 'Top']); }); - testWidgets('insertAll top', (WidgetTester tester) async { + testWidgetsWithLeakTracking('insertAll top', (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); final List buildOrder = []; + late final OverlayEntry baseEntry; + addTearDown(() => baseEntry..remove()..dispose()); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( key: overlayKey, initialEntries: [ - OverlayEntry( + baseEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add('Base'); return Container(); @@ -320,6 +351,11 @@ void main() { }, ), ]; + addTearDown(() { + for (final OverlayEntry entry in entries) { + entry..remove()..dispose(); + } + }); buildOrder.clear(); final OverlayState overlay = overlayKey.currentState! as OverlayState; @@ -329,17 +365,19 @@ void main() { expect(buildOrder, ['Base', 'New1', 'New2']); }); - testWidgets('insertAll below', (WidgetTester tester) async { + testWidgetsWithLeakTracking('insertAll below', (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); - OverlayEntry base; + late final OverlayEntry baseEntry; + addTearDown(() => baseEntry..remove()..dispose()); final List buildOrder = []; + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( key: overlayKey, initialEntries: [ - base = OverlayEntry( + baseEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add('Base'); return Container(); @@ -366,32 +404,41 @@ void main() { }, ), ]; + addTearDown(() { + for (final OverlayEntry entry in entries) { + entry..remove()..dispose(); + } + }); buildOrder.clear(); final OverlayState overlay = overlayKey.currentState! as OverlayState; - overlay.insertAll(entries, below: base); + overlay.insertAll(entries, below: baseEntry); await tester.pump(); expect(buildOrder, ['New1', 'New2','Base']); }); - testWidgets('insertAll above', (WidgetTester tester) async { + testWidgetsWithLeakTracking('insertAll above', (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); final List buildOrder = []; - OverlayEntry base; + late final OverlayEntry baseEntry; + addTearDown(() => baseEntry..remove()..dispose()); + late final OverlayEntry topEntry; + addTearDown(() => topEntry..remove()..dispose()); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( key: overlayKey, initialEntries: [ - base = OverlayEntry( + baseEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add('Base'); return Container(); }, ), - OverlayEntry( + topEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add('Top'); return Container(); @@ -418,16 +465,21 @@ void main() { }, ), ]; + addTearDown(() { + for (final OverlayEntry entry in entries) { + entry..remove()..dispose(); + } + }); buildOrder.clear(); final OverlayState overlay = overlayKey.currentState! as OverlayState; - overlay.insertAll(entries, above: base); + overlay.insertAll(entries, above: baseEntry); await tester.pump(); expect(buildOrder, ['Base', 'New1', 'New2', 'Top']); }); - testWidgets('rearrange', (WidgetTester tester) async { + testWidgetsWithLeakTracking('rearrange', (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); final List buildOrder = []; final List initialEntries = [ @@ -456,6 +508,11 @@ void main() { }, ), ]; + addTearDown(() { + for (final OverlayEntry entry in initialEntries) { + entry..remove()..dispose(); + } + }); await tester.pumpWidget( Directionality( @@ -469,9 +526,11 @@ void main() { expect(buildOrder, [0, 1, 2, 3]); + late final OverlayEntry newEntry; + addTearDown(() => newEntry..remove()..dispose()); final List rearranged = [ initialEntries[3], - OverlayEntry( + newEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add(4); return Container(); @@ -490,9 +549,10 @@ void main() { expect(buildOrder, [3, 4, 2, 0, 1]); }); - testWidgets('rearrange above', (WidgetTester tester) async { + testWidgetsWithLeakTracking('rearrange above', (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); final List buildOrder = []; + final List initialEntries = [ OverlayEntry( builder: (BuildContext context) { @@ -519,6 +579,11 @@ void main() { }, ), ]; + addTearDown(() { + for (final OverlayEntry entry in initialEntries) { + entry..remove()..dispose(); + } + }); await tester.pumpWidget( Directionality( @@ -532,9 +597,11 @@ void main() { expect(buildOrder, [0, 1, 2, 3]); + late final OverlayEntry newEntry; + addTearDown(() => newEntry..remove()..dispose()); final List rearranged = [ initialEntries[3], - OverlayEntry( + newEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add(4); return Container(); @@ -553,7 +620,7 @@ void main() { expect(buildOrder, [3, 4, 2, 1, 0]); }); - testWidgets('rearrange below', (WidgetTester tester) async { + testWidgetsWithLeakTracking('rearrange below', (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); final List buildOrder = []; final List initialEntries = [ @@ -582,6 +649,11 @@ void main() { }, ), ]; + addTearDown(() { + for (final OverlayEntry entry in initialEntries) { + entry..remove()..dispose(); + } + }); await tester.pumpWidget( Directionality( @@ -595,9 +667,11 @@ void main() { expect(buildOrder, [0, 1, 2, 3]); + late final OverlayEntry newEntry; + addTearDown(() => newEntry..remove()..dispose()); final List rearranged = [ initialEntries[3], - OverlayEntry( + newEntry = OverlayEntry( builder: (BuildContext context) { buildOrder.add(4); return Container(); @@ -694,7 +768,7 @@ void main() { await tester.pump(); }); - testWidgets('OverlayState.of() throws when called if an Overlay does not exist', (WidgetTester tester) async { + testWidgetsWithLeakTracking('OverlayState.of() throws when called if an Overlay does not exist', (WidgetTester tester) async { await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -740,9 +814,11 @@ void main() { ); }); - testWidgets("OverlayState.maybeOf() works when an Overlay does and doesn't exist", (WidgetTester tester) async { + testWidgetsWithLeakTracking("OverlayState.maybeOf() works when an Overlay does and doesn't exist", (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); OverlayState? foundState; + late final OverlayEntry baseEntry; + addTearDown(() => baseEntry..remove()..dispose()); await tester.pumpWidget( Directionality( @@ -750,7 +826,7 @@ void main() { child: Overlay( key: overlayKey, initialEntries: [ - OverlayEntry( + baseEntry = OverlayEntry( builder: (BuildContext context) { foundState = Overlay.maybeOf(context); return Container(); @@ -781,7 +857,7 @@ void main() { expect(foundState, isNull); }); - testWidgets('OverlayEntry.opaque can be changed when OverlayEntry is not part of an Overlay (yet)', (WidgetTester tester) async { + testWidgetsWithLeakTracking('OverlayEntry.opaque can be changed when OverlayEntry is not part of an Overlay (yet)', (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); final Key root = UniqueKey(); final Key top = UniqueKey(); @@ -790,6 +866,7 @@ void main() { return Container(key: root); }, ); + addTearDown(() => rootEntry..remove()..dispose()); await tester.pumpWidget( Directionality( @@ -810,6 +887,7 @@ void main() { return Container(key: top); }, ); + addTearDown(() => newEntry..remove()..dispose()); expect(newEntry.opaque, isFalse); newEntry.opaque = true; // Does neither trigger an assert nor throw. expect(newEntry.opaque, isTrue); @@ -822,7 +900,7 @@ void main() { expect(find.byKey(top), findsOneWidget); }); - testWidgets('OverlayEntries do not rebuild when opaqueness changes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('OverlayEntries do not rebuild when opaqueness changes', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/45797. final GlobalKey overlayKey = GlobalKey(); @@ -839,18 +917,21 @@ void main() { return bottomWidget; }, ); + addTearDown(() => bottomEntry..remove()..dispose()); final OverlayEntry middleEntry = OverlayEntry( maintainState: true, builder: (BuildContext context) { return middleWidget; }, ); + addTearDown(() => middleEntry..remove()..dispose()); final OverlayEntry topEntry = OverlayEntry( maintainState: true, builder: (BuildContext context) { return topWidget; }, ); + addTearDown(() => topEntry..remove()..dispose()); await tester.pumpWidget( Directionality( @@ -881,7 +962,7 @@ void main() { expect(tester.state(find.byKey(top)).rebuildCount, 1); }); - testWidgets('OverlayEntries do not rebuild when opaque entry is added', (WidgetTester tester) async { + testWidgetsWithLeakTracking('OverlayEntries do not rebuild when opaque entry is added', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/45797. final GlobalKey overlayKey = GlobalKey(); @@ -898,6 +979,7 @@ void main() { return bottomWidget; }, ); + addTearDown(() => bottomEntry..remove()..dispose()); final OverlayEntry middleEntry = OverlayEntry( opaque: true, maintainState: true, @@ -905,12 +987,14 @@ void main() { return middleWidget; }, ); + addTearDown(() => middleEntry..remove()..dispose()); final OverlayEntry topEntry = OverlayEntry( maintainState: true, builder: (BuildContext context) { return topWidget; }, ); + addTearDown(() => topEntry..remove()..dispose()); await tester.pumpWidget( Directionality( @@ -941,16 +1025,19 @@ void main() { expect(tester.state(find.byKey(top)).rebuildCount, 1); }); - testWidgets('entries below opaque entries are ignored for hit testing', (WidgetTester tester) async { + testWidgetsWithLeakTracking('entries below opaque entries are ignored for hit testing', (WidgetTester tester) async { final GlobalKey overlayKey = GlobalKey(); int bottomTapCount = 0; + late final OverlayEntry baseEntry; + addTearDown(() => baseEntry..remove()..dispose()); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( key: overlayKey, initialEntries: [ - OverlayEntry( + baseEntry = OverlayEntry( maintainState: true, builder: (BuildContext context) { return GestureDetector( @@ -969,13 +1056,17 @@ void main() { await tester.tap(find.byKey(overlayKey), warnIfMissed: false); // gesture detector is translucent; no hit is registered between it and the render view expect(bottomTapCount, 1); - overlayKey.currentState!.insert(OverlayEntry( - maintainState: true, - opaque: true, - builder: (BuildContext context) { - return Container(); - }, - )); + late final OverlayEntry newEntry1; + addTearDown(() => newEntry1..remove()..dispose()); + overlayKey.currentState!.insert( + newEntry1 = OverlayEntry( + maintainState: true, + opaque: true, + builder: (BuildContext context) { + return Container(); + }, + ), + ); await tester.pump(); // Bottom is offstage and does not receive tap events. @@ -985,17 +1076,21 @@ void main() { expect(bottomTapCount, 1); int topTapCount = 0; - overlayKey.currentState!.insert(OverlayEntry( - maintainState: true, - opaque: true, - builder: (BuildContext context) { - return GestureDetector( - onTap: () { - topTapCount++; - }, - ); - }, - )); + late final OverlayEntry newEntry2; + addTearDown(() => newEntry2..remove()..dispose()); + overlayKey.currentState!.insert( + newEntry2 = OverlayEntry( + maintainState: true, + opaque: true, + builder: (BuildContext context) { + return GestureDetector( + onTap: () { + topTapCount++; + }, + ); + }, + ), + ); await tester.pump(); expect(topTapCount, 0); @@ -1004,22 +1099,27 @@ void main() { expect(bottomTapCount, 1); }); - testWidgets('Semantics of entries below opaque entries are ignored', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics of entries below opaque entries are ignored', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); final GlobalKey overlayKey = GlobalKey(); + late final OverlayEntry bottomEntry; + addTearDown(() => bottomEntry..remove()..dispose()); + late final OverlayEntry topEntry; + addTearDown(() => topEntry..remove()..dispose()); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( key: overlayKey, initialEntries: [ - OverlayEntry( + bottomEntry = OverlayEntry( maintainState: true, builder: (BuildContext context) { return const Text('bottom'); }, ), - OverlayEntry( + topEntry = OverlayEntry( maintainState: true, opaque: true, builder: (BuildContext context) { @@ -1039,13 +1139,16 @@ void main() { semantics.dispose(); }); - testWidgets('Can use Positioned within OverlayEntry', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can use Positioned within OverlayEntry', (WidgetTester tester) async { + late final OverlayEntry baseEntry; + addTearDown(() => baseEntry..remove()..dispose()); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( initialEntries: [ - OverlayEntry( + baseEntry = OverlayEntry( builder: (BuildContext context) { return const Positioned( left: 145, @@ -1117,13 +1220,16 @@ void main() { } }); - testWidgets('Overlay always applies clip', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Overlay always applies clip', (WidgetTester tester) async { + late final OverlayEntry baseEntry; + addTearDown(() => baseEntry..remove()..dispose()); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( initialEntries: [ - OverlayEntry( + baseEntry = OverlayEntry( builder: (BuildContext context) => Positioned(left: 10, right: 10, child: Container()), ), ], @@ -1139,7 +1245,7 @@ void main() { ); }); - testWidgets('OverlayEntry throws if inserted to an invalid Overlay', (WidgetTester tester) async { + testWidgetsWithLeakTracking('OverlayEntry throws if inserted to an invalid Overlay', (WidgetTester tester) async { await tester.pumpWidget( const Directionality( textDirection: TextDirection.ltr, @@ -1148,6 +1254,7 @@ void main() { ); final OverlayState overlay = tester.state(find.byType(Overlay)); final OverlayEntry entry = OverlayEntry(builder: (BuildContext context) => const SizedBox()); + addTearDown(() => entry..remove()..dispose()); expect( () => overlay.insert(entry), returnsNormally, @@ -1212,13 +1319,14 @@ void main() { child: Overlay(key: overlayKey), ); - testWidgets('mounted state can be listened', (WidgetTester tester) async { + testWidgetsWithLeakTracking('mounted state can be listened', (WidgetTester tester) async { await tester.pumpWidget(emptyOverlay); final OverlayState overlay = overlayKey.currentState! as OverlayState; final List mountedLog = []; final OverlayEntry entry = OverlayEntry( builder: (BuildContext context) => Container(), ); + addTearDown(entry.dispose); entry.addListener(() { mountedLog.add(entry.mounted); @@ -1245,12 +1353,13 @@ void main() { expect(mountedLog, [true, false, true, false]); }); - testWidgets('throw if disposed before removal', (WidgetTester tester) async { + testWidgetsWithLeakTracking('throw if disposed before removal', (WidgetTester tester) async { await tester.pumpWidget(emptyOverlay); final OverlayState overlay = overlayKey.currentState! as OverlayState; final OverlayEntry entry = OverlayEntry( builder: (BuildContext context) => Container(), ); + addTearDown(() => entry..remove()..dispose()); overlay.insert(entry); Object? error; @@ -1279,7 +1388,7 @@ void main() { expect(error, isAssertionError); }); - testWidgets('delayed dispose', (WidgetTester tester) async { + testWidgetsWithLeakTracking('delayed dispose', (WidgetTester tester) async { await tester.pumpWidget(emptyOverlay); final OverlayState overlay = overlayKey.currentState! as OverlayState; final List mountedLog = []; @@ -1315,15 +1424,17 @@ void main() { }); group('LookupBoundary', () { - testWidgets('hides Overlay from Overlay.maybeOf', (WidgetTester tester) async { + testWidgetsWithLeakTracking('hides Overlay from Overlay.maybeOf', (WidgetTester tester) async { OverlayState? overlay; + late final OverlayEntry baseEntry; + addTearDown(() => baseEntry..remove()..dispose()); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( initialEntries: [ - OverlayEntry( + baseEntry = OverlayEntry( builder: (BuildContext context) { return LookupBoundary( child: Builder( @@ -1343,13 +1454,16 @@ void main() { expect(overlay, isNull); }); - testWidgets('hides Overlay from Overlay.of', (WidgetTester tester) async { + testWidgetsWithLeakTracking('hides Overlay from Overlay.of', (WidgetTester tester) async { + late final OverlayEntry baseEntry; + addTearDown(() => baseEntry..remove()..dispose()); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( initialEntries: [ - OverlayEntry( + baseEntry = OverlayEntry( builder: (BuildContext context) { return LookupBoundary( child: Builder( @@ -1386,13 +1500,16 @@ void main() { ); }); - testWidgets('hides Overlay from debugCheckHasOverlay', (WidgetTester tester) async { + testWidgetsWithLeakTracking('hides Overlay from debugCheckHasOverlay', (WidgetTester tester) async { + late final OverlayEntry baseEntry; + addTearDown(() => baseEntry..remove()..dispose()); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Overlay( initialEntries: [ - OverlayEntry( + baseEntry = OverlayEntry( builder: (BuildContext context) { return LookupBoundary( child: Builder( diff --git a/packages/flutter/test/widgets/page_view_test.dart b/packages/flutter/test/widgets/page_view_test.dart index 41405b00e229e..ef97dd4617c9d 100644 --- a/packages/flutter/test/widgets/page_view_test.dart +++ b/packages/flutter/test/widgets/page_view_test.dart @@ -1265,4 +1265,39 @@ void main() { // Check the stretch factor in the first element of the transform matrix. expect(transform.transform.storage.first, 1.0); }); + + testWidgetsWithLeakTracking('PageController onAttach, onDetach', (WidgetTester tester) async { + int attach = 0; + int detach = 0; + final PageController controller = PageController( + onAttach: (_) { attach++; }, + onDetach: (_) { detach++; }, + ); + addTearDown(controller.dispose); + + await tester.pumpWidget(MaterialApp( + theme: ThemeData(useMaterial3: true), + home: Center( + child: PageView( + controller: controller, + physics: const PageScrollPhysics().applyTo(const ClampingScrollPhysics()), + children: const [ + Center(child: Text('First Page')), + Center(child: Text('Second Page')), + Center(child: Text('Third Page')), + ], + ), + ), + )); + await tester.pumpAndSettle(); + + expect(attach, 1); + expect(detach, 0); + + await tester.pumpWidget(Container()); + await tester.pumpAndSettle(); + + expect(attach, 1); + expect(detach, 1); + }); } diff --git a/packages/flutter/test/widgets/router_restoration_test.dart b/packages/flutter/test/widgets/router_restoration_test.dart index 4d429c893d1b0..109dee1c0343f 100644 --- a/packages/flutter/test/widgets/router_restoration_test.dart +++ b/packages/flutter/test/widgets/router_restoration_test.dart @@ -5,9 +5,10 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { - testWidgets('Router state restoration without RouteInformationProvider', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Router state restoration without RouteInformationProvider', (WidgetTester tester) async { final UniqueKey router = UniqueKey(); _TestRouterDelegate delegate() => tester.widget>(find.byKey(router)).routerDelegate as _TestRouterDelegate; @@ -39,7 +40,12 @@ void main() { expect(find.text('Current config: /foo'), findsOneWidget); expect(delegate().newRoutePaths, isEmpty); expect(delegate().restoredRoutePaths, ['/foo', '/foo']); - }); + }, + leakTrackingTestConfig: const LeakTrackingTestConfig( + // TODO(ksokolovskyi): remove after fixing + // https://github.com/flutter/flutter/issues/134205 + notDisposedAllowList: {'_RestorableRouteInformation': 2}, + )); testWidgets('Router state restoration with RouteInformationProvider', (WidgetTester tester) async { final UniqueKey router = UniqueKey(); @@ -152,22 +158,37 @@ class _TestRouteInformationProvider extends RouteInformationProvider with Change } } -class _TestWidget extends StatelessWidget { +class _TestWidget extends StatefulWidget { const _TestWidget({this.withInformationProvider = false, this.routerKey}); final bool withInformationProvider; final Key? routerKey; + @override + State<_TestWidget> createState() => _TestWidgetState(); +} + +class _TestWidgetState extends State<_TestWidget> { + final _TestRouterDelegate _delegate = _TestRouterDelegate(); + final _TestRouteInformationProvider _routeInformationProvider = _TestRouteInformationProvider(); + + @override + void dispose() { + _delegate.dispose(); + _routeInformationProvider.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return RootRestorationScope( restorationId: 'root', child: Router( - key: routerKey, + key: widget.routerKey, restorationScopeId: 'router', - routerDelegate: _TestRouterDelegate(), + routerDelegate: _delegate, routeInformationParser: _TestRouteInformationParser(), - routeInformationProvider: withInformationProvider ? _TestRouteInformationProvider() : null, + routeInformationProvider: widget.withInformationProvider ? _routeInformationProvider : null, ), ); } diff --git a/packages/flutter/test/widgets/scrollable_test.dart b/packages/flutter/test/widgets/scrollable_test.dart index e7576552f6b24..14d6ba63ecf54 100644 --- a/packages/flutter/test/widgets/scrollable_test.dart +++ b/packages/flutter/test/widgets/scrollable_test.dart @@ -861,12 +861,13 @@ void main() { expect(targetMidLeftPage1, findsOneWidget); }); - testWidgets('ensureVisible does not move TabViews', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ensureVisible does not move TabViews', (WidgetTester tester) async { final TickerProvider vsync = TestTickerProvider(); final TabController controller = TabController( length: 3, vsync: vsync, ); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( diff --git a/packages/flutter/test/widgets/selectable_region_test.dart b/packages/flutter/test/widgets/selectable_region_test.dart index 717ba3d5f1825..4be55348f5d2d 100644 --- a/packages/flutter/test/widgets/selectable_region_test.dart +++ b/packages/flutter/test/widgets/selectable_region_test.dart @@ -281,7 +281,7 @@ void main() { semantics.dispose(); }); - testWidgetsWithLeakTracking('mouse selection always cancels previous selection', (WidgetTester tester) async { + testWidgets('mouse single-click selection collapses the selection', (WidgetTester tester) async { final UniqueKey spy = UniqueKey(); final FocusNode focusNode = FocusNode(); addTearDown(focusNode.dispose); @@ -300,9 +300,14 @@ void main() { final RenderSelectionSpy renderSelectionSpy = tester.renderObject(find.byKey(spy)); final TestGesture gesture = await tester.startGesture(const Offset(200.0, 200.0), kind: PointerDeviceKind.mouse); addTearDown(gesture.removePointer); + await tester.pump(); + await gesture.up(); await tester.pumpAndSettle(); - expect(renderSelectionSpy.events.length, 1); - expect(renderSelectionSpy.events[0], isA()); + expect(renderSelectionSpy.events.length, 2); + expect(renderSelectionSpy.events[0], isA()); + expect((renderSelectionSpy.events[0] as SelectionEdgeUpdateEvent).type, SelectionEventType.startEdgeUpdate); + expect(renderSelectionSpy.events[1], isA()); + expect((renderSelectionSpy.events[1] as SelectionEdgeUpdateEvent).type, SelectionEventType.endEdgeUpdate); }, skip: kIsWeb); // https://github.com/flutter/flutter/issues/102410. testWidgetsWithLeakTracking('touch long press sends select-word event', (WidgetTester tester) async { @@ -474,7 +479,7 @@ void main() { await tester.pump(const Duration(milliseconds: 500)); await gesture.up(); expect( - renderSelectionSpy.events.every((SelectionEvent element) => element is ClearSelectionEvent), + renderSelectionSpy.events.every((SelectionEvent element) => element is SelectionEdgeUpdateEvent), isTrue, ); }); @@ -543,7 +548,7 @@ void main() { }, variant: TargetPlatformVariant.all()); group('SelectionArea integration', () { - testWidgetsWithLeakTracking('mouse can select single text', (WidgetTester tester) async { + testWidgets('mouse can select single text on desktop platforms', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); addTearDown(focusNode.dispose); @@ -574,13 +579,17 @@ void main() { // Check backward selection. await gesture.moveTo(textOffsetToPosition(paragraph, 1)); await tester.pump(); + expect(paragraph.selections.isEmpty, isFalse); expect(paragraph.selections[0], const TextSelection(baseOffset: 2, extentOffset: 1)); // Start a new drag. await gesture.up(); + await tester.pumpAndSettle(); + await gesture.down(textOffsetToPosition(paragraph, 5)); await tester.pumpAndSettle(); - expect(paragraph.selections.isEmpty, isTrue); + expect(paragraph.selections.isEmpty, isFalse); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 5)); // Selecting across line should select to the end. await gesture.moveTo(textOffsetToPosition(paragraph, 5) + const Offset(0.0, 200.0)); @@ -588,7 +597,60 @@ void main() { expect(paragraph.selections[0], const TextSelection(baseOffset: 5, extentOffset: 11)); await gesture.up(); - }); + }, variant: TargetPlatformVariant.desktop()); + + testWidgetsWithLeakTracking('mouse can select single text on mobile platforms', (WidgetTester tester) async { + final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); + + await tester.pumpWidget( + MaterialApp( + home: SelectableRegion( + focusNode: focusNode, + selectionControls: materialTextSelectionControls, + child: const Center( + child: Text('How are you'), + ), + ), + ), + ); + final RenderParagraph paragraph = tester.renderObject(find.descendant(of: find.text('How are you'), matching: find.byType(RichText))); + final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph, 2), kind: PointerDeviceKind.mouse); + addTearDown(gesture.removePointer); + await tester.pump(); + + await gesture.moveTo(textOffsetToPosition(paragraph, 4)); + await tester.pump(); + expect(paragraph.selections[0], const TextSelection(baseOffset: 2, extentOffset: 4)); + + await gesture.moveTo(textOffsetToPosition(paragraph, 6)); + await tester.pump(); + expect(paragraph.selections[0], const TextSelection(baseOffset: 2, extentOffset: 6)); + + // Check backward selection. + await gesture.moveTo(textOffsetToPosition(paragraph, 1)); + await tester.pump(); + expect(paragraph.selections.isEmpty, isFalse); + expect(paragraph.selections[0], const TextSelection(baseOffset: 2, extentOffset: 1)); + + // Start a new drag. + await gesture.up(); + await tester.pumpAndSettle(); + + await gesture.down(textOffsetToPosition(paragraph, 5)); + await tester.pumpAndSettle(); + await gesture.moveTo(textOffsetToPosition(paragraph, 6)); + await tester.pump(); + expect(paragraph.selections.isEmpty, isFalse); + expect(paragraph.selections[0], const TextSelection(baseOffset: 5, extentOffset: 6)); + + // Selecting across line should select to the end. + await gesture.moveTo(textOffsetToPosition(paragraph, 5) + const Offset(0.0, 200.0)); + await tester.pump(); + expect(paragraph.selections[0], const TextSelection(baseOffset: 5, extentOffset: 11)); + + await gesture.up(); + }, variant: TargetPlatformVariant.mobile()); testWidgetsWithLeakTracking('mouse can select word-by-word on double click drag', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); @@ -643,7 +705,8 @@ void main() { await gesture.down(textOffsetToPosition(paragraph, 5)); await tester.pump(); await gesture.up(); - expect(paragraph.selections.isEmpty, isTrue); + expect(paragraph.selections.isEmpty, isFalse); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 5)); await tester.pump(kDoubleTapTimeout); // Double-click. @@ -761,13 +824,13 @@ void main() { // Should clear the selection on paragraph 3. expect(paragraph1.selections[0], const TextSelection(baseOffset: 0, extentOffset: 12)); expect(paragraph2.selections[0], const TextSelection(baseOffset: 0, extentOffset: 6)); - expect(paragraph3.selections.isEmpty, true); + expect(paragraph3.selections.isEmpty, isTrue); await gesture.moveTo(textOffsetToPosition(paragraph1, 4)); // Should clear the selection on paragraph 2. expect(paragraph1.selections[0], const TextSelection(baseOffset: 0, extentOffset: 7)); - expect(paragraph2.selections.isEmpty, true); - expect(paragraph3.selections.isEmpty, true); + expect(paragraph2.selections.isEmpty, isTrue); + expect(paragraph3.selections.isEmpty, isTrue); await gesture.up(); }, skip: kIsWeb); // https://github.com/flutter/flutter/issues/125582. @@ -863,6 +926,52 @@ void main() { await gesture.up(); }); + testWidgetsWithLeakTracking('collapsing selection should clear selection of all other selectables', (WidgetTester tester) async { + final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); + + await tester.pumpWidget( + MaterialApp( + home: SelectableRegion( + focusNode: focusNode, + selectionControls: materialTextSelectionControls, + child: const Column( + children: [ + Text('How are you?'), + Text('Good, and you?'), + Text('Fine, thank you.'), + ], + ), + ), + ), + ); + final RenderParagraph paragraph1 = tester.renderObject(find.descendant(of: find.text('How are you?'), matching: find.byType(RichText))); + final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph1, 2), kind: PointerDeviceKind.mouse); + addTearDown(gesture.removePointer); + await tester.pump(); + await gesture.up(); + await tester.pumpAndSettle(); + expect(paragraph1.selections[0], const TextSelection.collapsed(offset: 2)); + + final RenderParagraph paragraph2 = tester.renderObject(find.descendant(of: find.text('Good, and you?'), matching: find.byType(RichText))); + await gesture.down(textOffsetToPosition(paragraph2, 5)); + await tester.pump(); + await gesture.up(); + await tester.pumpAndSettle(); + expect(paragraph1.selections.isEmpty, isTrue); + expect(paragraph2.selections[0], const TextSelection.collapsed(offset: 5)); + + final RenderParagraph paragraph3 = tester.renderObject(find.descendant(of: find.text('Fine, thank you.'), matching: find.byType(RichText))); + await gesture.down(textOffsetToPosition(paragraph3, 13)); + await tester.pump(); + await gesture.up(); + await tester.pumpAndSettle(); + + expect(paragraph1.selections.isEmpty, isTrue); + expect(paragraph2.selections.isEmpty, isTrue); + expect(paragraph3.selections[0], const TextSelection.collapsed(offset: 13)); + }); + testWidgetsWithLeakTracking('mouse can work with disabled container', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(); addTearDown(focusNode.dispose); @@ -1108,10 +1217,11 @@ void main() { expect(buttonTypes, contains(ContextMenuButtonType.selectAll)); expect(find.byKey(toolbarKey), findsOneWidget); - // Clear selection. + // Collapse selection. await tester.tapAt(textOffsetToPosition(paragraph, 9)); await tester.pump(); - expect(paragraph.selections.isEmpty, true); + expect(paragraph.selections.isEmpty, isFalse); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 9)); expect(find.byKey(toolbarKey), findsNothing); }, variant: TargetPlatformVariant.only(TargetPlatform.iOS), @@ -1151,7 +1261,9 @@ void main() { expect(find.byKey(toolbarKey), findsNothing); final RenderParagraph paragraph = tester.renderObject(find.descendant(of: find.text('How are you'), matching: find.byType(RichText))); + final TestGesture primaryMouseButtonGesture = await tester.createGesture(kind: PointerDeviceKind.mouse); final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph, 2), kind: PointerDeviceKind.mouse, buttons: kSecondaryMouseButton); + addTearDown(primaryMouseButtonGesture.removePointer); addTearDown(gesture.removePointer); await tester.pump(); expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 3)); @@ -1185,10 +1297,14 @@ void main() { expect(buttonTypes, contains(ContextMenuButtonType.selectAll)); expect(find.byKey(toolbarKey), findsOneWidget); - // Clear selection. - await tester.tapAt(textOffsetToPosition(paragraph, 1)); + // Collapse selection. + await primaryMouseButtonGesture.down(textOffsetToPosition(paragraph, 1)); await tester.pump(); - expect(paragraph.selections.isEmpty, true); + await primaryMouseButtonGesture.up(); + await tester.pumpAndSettle(); + // Selection is collapsed. + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 1)); expect(find.byKey(toolbarKey), findsNothing); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS }), @@ -1229,6 +1345,8 @@ void main() { final RenderParagraph paragraph = tester.renderObject(find.descendant(of: find.text('How are you'), matching: find.byType(RichText))); final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph, 2), kind: PointerDeviceKind.mouse, buttons: kSecondaryMouseButton); + final TestGesture primaryMouseButtonGesture = await tester.createGesture(kind: PointerDeviceKind.mouse); + addTearDown(primaryMouseButtonGesture.removePointer); addTearDown(gesture.removePointer); await tester.pump(); expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 3)); @@ -1286,10 +1404,14 @@ void main() { expect(buttonTypes, contains(ContextMenuButtonType.selectAll)); expect(find.byKey(toolbarKey), findsOneWidget); - // Clear selection. - await tester.tapAt(textOffsetToPosition(paragraph, 1)); + // Collapse selection. + await primaryMouseButtonGesture.down(textOffsetToPosition(paragraph, 1)); await tester.pump(); - expect(paragraph.selections.isEmpty, true); + await primaryMouseButtonGesture.up(); + await tester.pumpAndSettle(); + // Selection is collapsed. + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 1)); expect(find.byKey(toolbarKey), findsNothing); }, variant: TargetPlatformVariant.only(TargetPlatform.macOS), @@ -1330,21 +1452,24 @@ void main() { final RenderParagraph paragraph = tester.renderObject(find.descendant(of: find.text('How are you'), matching: find.byType(RichText))); final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph, 2), kind: PointerDeviceKind.mouse, buttons: kSecondaryMouseButton); + final TestGesture primaryMouseButtonGesture = await tester.createGesture(kind: PointerDeviceKind.mouse); + addTearDown(primaryMouseButtonGesture.removePointer); addTearDown(gesture.removePointer); await tester.pump(); - // Selection is collapsed so none is reported. - expect(paragraph.selections.isEmpty, true); - await gesture.up(); await tester.pump(); + // Selection is collapsed. + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 2)); expect(buttonTypes.length, 1); expect(buttonTypes, contains(ContextMenuButtonType.selectAll)); expect(find.byKey(toolbarKey), findsOneWidget); await gesture.down(textOffsetToPosition(paragraph, 6)); await tester.pump(); - expect(paragraph.selections.isEmpty, true); + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 6)); await gesture.up(); await tester.pump(); @@ -1355,7 +1480,8 @@ void main() { await gesture.down(textOffsetToPosition(paragraph, 9)); await tester.pump(); - expect(paragraph.selections.isEmpty, true); + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 9)); await gesture.up(); await tester.pump(); @@ -1364,20 +1490,23 @@ void main() { expect(buttonTypes, contains(ContextMenuButtonType.selectAll)); expect(find.byKey(toolbarKey), findsOneWidget); - // Clear selection. - await tester.tapAt(textOffsetToPosition(paragraph, 1)); + // Collapse selection. + await primaryMouseButtonGesture.down(textOffsetToPosition(paragraph, 1)); await tester.pump(); - expect(paragraph.selections.isEmpty, true); + await primaryMouseButtonGesture.up(); + await tester.pumpAndSettle(kDoubleTapTimeout); + // Selection is collapsed. + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 1)); expect(find.byKey(toolbarKey), findsNothing); // Create an uncollapsed selection by dragging. - final TestGesture dragGesture = await tester.startGesture(textOffsetToPosition(paragraph, 0), kind: PointerDeviceKind.mouse); - addTearDown(dragGesture.removePointer); + await primaryMouseButtonGesture.down(textOffsetToPosition(paragraph, 0)); await tester.pump(); - await dragGesture.moveTo(textOffsetToPosition(paragraph, 5)); + await primaryMouseButtonGesture.moveTo(textOffsetToPosition(paragraph, 5)); await tester.pump(); expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 5)); - await dragGesture.up(); + await primaryMouseButtonGesture.up(); await tester.pump(); // Right click on previous selection should not collapse the selection. @@ -1394,13 +1523,18 @@ void main() { await tester.pump(); await gesture.up(); await tester.pump(); - expect(paragraph.selections.isEmpty, true); + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 7)); expect(find.byKey(toolbarKey), findsOneWidget); - // Clear selection. - await tester.tapAt(textOffsetToPosition(paragraph, 1)); + // Collapse selection. + await primaryMouseButtonGesture.down(textOffsetToPosition(paragraph, 1)); await tester.pump(); - expect(paragraph.selections.isEmpty, true); + await primaryMouseButtonGesture.up(); + await tester.pumpAndSettle(); + // Selection is collapsed. + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 1)); expect(find.byKey(toolbarKey), findsNothing); }, variant: const TargetPlatformVariant({ TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.windows }), @@ -1441,13 +1575,15 @@ void main() { final RenderParagraph paragraph = tester.renderObject(find.descendant(of: find.text('How are you'), matching: find.byType(RichText))); final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph, 2), kind: PointerDeviceKind.mouse, buttons: kSecondaryMouseButton); + final TestGesture primaryMouseButtonGesture = await tester.createGesture(kind: PointerDeviceKind.mouse); + addTearDown(primaryMouseButtonGesture.removePointer); addTearDown(gesture.removePointer); await tester.pump(); - // Selection is collapsed so none is reported. - expect(paragraph.selections.isEmpty, true); - await gesture.up(); await tester.pump(); + // Selection is collapsed. + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 2)); // Context menu toggled on. expect(buttonTypes.length, 1); @@ -1456,17 +1592,18 @@ void main() { await gesture.down(textOffsetToPosition(paragraph, 6)); await tester.pump(); - expect(paragraph.selections.isEmpty, true); - await gesture.up(); await tester.pump(); + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 2)); - // Context menu toggled off. + // Context menu toggled off. Selection remains the same. expect(find.byKey(toolbarKey), findsNothing); await gesture.down(textOffsetToPosition(paragraph, 9)); await tester.pump(); - expect(paragraph.selections.isEmpty, true); + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 9)); await gesture.up(); await tester.pump(); @@ -1476,19 +1613,22 @@ void main() { expect(buttonTypes, contains(ContextMenuButtonType.selectAll)); expect(find.byKey(toolbarKey), findsOneWidget); - // Clear selection. - await tester.tapAt(textOffsetToPosition(paragraph, 1)); + // Collapse selection. + await primaryMouseButtonGesture.down(textOffsetToPosition(paragraph, 1)); await tester.pump(); - expect(paragraph.selections.isEmpty, true); + await primaryMouseButtonGesture.up(); + await tester.pumpAndSettle(kDoubleTapTimeout); + // Selection is collapsed. + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 1)); expect(find.byKey(toolbarKey), findsNothing); - final TestGesture dragGesture = await tester.startGesture(textOffsetToPosition(paragraph, 0), kind: PointerDeviceKind.mouse); - addTearDown(dragGesture.removePointer); + await primaryMouseButtonGesture.down(textOffsetToPosition(paragraph, 0)); await tester.pump(); - await dragGesture.moveTo(textOffsetToPosition(paragraph, 5)); + await primaryMouseButtonGesture.moveTo(textOffsetToPosition(paragraph, 5)); await tester.pump(); expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 5)); - await dragGesture.up(); + await primaryMouseButtonGesture.up(); await tester.pump(); // Right click on previous selection should not collapse the selection. @@ -1514,13 +1654,18 @@ void main() { await tester.pump(); await gesture.up(); await tester.pump(); - expect(paragraph.selections.isEmpty, true); + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 7)); expect(find.byKey(toolbarKey), findsOneWidget); - // Clear selection. - await tester.tapAt(textOffsetToPosition(paragraph, 1)); + // Collapse selection. + await primaryMouseButtonGesture.down(textOffsetToPosition(paragraph, 1)); await tester.pump(); - expect(paragraph.selections.isEmpty, true); + await primaryMouseButtonGesture.up(); + await tester.pumpAndSettle(); + // Selection is collapsed. + expect(paragraph.selections.isEmpty, false); + expect(paragraph.selections[0], const TextSelection.collapsed(offset: 1)); expect(find.byKey(toolbarKey), findsNothing); }, variant: TargetPlatformVariant.only(TargetPlatform.linux), @@ -2414,7 +2559,9 @@ void main() { expect(paragraph1.selections.length, 1); expect(paragraph1.selections[0].start, 2); expect(paragraph1.selections[0].end, 12); - expect(paragraph2.selections.length, 0); + expect(paragraph2.selections.length, 1); + expect(paragraph2.selections[0].start, 0); + expect(paragraph2.selections[0].end, 0); await sendKeyCombination(tester, SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, alt: alt, control: control)); await tester.pump(); @@ -2424,7 +2571,9 @@ void main() { expect(paragraph1.selections.length, 1); expect(paragraph1.selections[0].start, 2); expect(paragraph1.selections[0].end, 8); - expect(paragraph2.selections.length, 0); + expect(paragraph2.selections.length, 1); + expect(paragraph2.selections[0].start, 0); + expect(paragraph2.selections[0].end, 0); }, variant: TargetPlatformVariant.all()); testWidgetsWithLeakTracking('can use keyboard to granularly extend selection - line', (WidgetTester tester) async { @@ -2507,7 +2656,9 @@ void main() { expect(paragraph1.selections.length, 1); expect(paragraph1.selections[0].start, 2); expect(paragraph1.selections[0].end, 12); - expect(paragraph2.selections.length, 0); + expect(paragraph2.selections.length, 1); + expect(paragraph2.selections[0].start, 0); + expect(paragraph2.selections[0].end, 0); await sendKeyCombination(tester, SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, alt: alt, meta: meta)); await tester.pump(); @@ -2594,8 +2745,12 @@ void main() { expect(paragraph1.selections.length, 1); expect(paragraph1.selections[0].start, 0); expect(paragraph1.selections[0].end, 2); - expect(paragraph2.selections.length, 0); - expect(paragraph3.selections.length, 0); + expect(paragraph2.selections.length, 1); + expect(paragraph2.selections[0].start, 0); + expect(paragraph2.selections[0].end, 0); + expect(paragraph3.selections.length, 1); + expect(paragraph3.selections[0].start, 0); + expect(paragraph3.selections[0].end, 0); }, variant: TargetPlatformVariant.all()); testWidgetsWithLeakTracking('can use keyboard to directionally extend selection', (WidgetTester tester) async { @@ -2666,7 +2821,9 @@ void main() { expect(paragraph2.selections.length, 1); expect(paragraph2.selections[0].start, 2); expect(paragraph2.selections[0].end, 6); - expect(paragraph3.selections.length, 0); + expect(paragraph3.selections.length, 1); + expect(paragraph3.selections[0].start, 0); + expect(paragraph3.selections[0].end, 0); await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp, shift: true)); await tester.pump(); @@ -3017,8 +3174,14 @@ void main() { // Backwards selection. await mouseGesture.down(textOffsetToPosition(paragraph, 3)); - await tester.pumpAndSettle(); - expect(content, isNull); + await tester.pump(); + await mouseGesture.up(); + await tester.pumpAndSettle(kDoubleTapTimeout); + expect(content, isNotNull); + expect(content!.plainText, ''); + + await mouseGesture.down(textOffsetToPosition(paragraph, 3)); + await tester.pump(); await mouseGesture.moveTo(textOffsetToPosition(paragraph, 0)); await tester.pumpAndSettle(); @@ -3045,9 +3208,10 @@ void main() { // Called on tap. await mouseGesture.down(textOffsetToPosition(paragraph, 0)); await tester.pumpAndSettle(); - expect(content, isNull); await mouseGesture.up(); - await tester.pumpAndSettle(); + await tester.pumpAndSettle(kDoubleTapTimeout); + expect(content, isNotNull); + expect(content!.plainText, ''); // With touch gestures. @@ -3224,7 +3388,7 @@ void main() { expect(paragraph2.selections.length, 1); expect(paragraph2.selections[0].start, 0); expect(paragraph2.selections[0].end, 8); - expect(paragraph3.selections.length, 0); + expect(paragraph3.selections.length, 1); expect(content, isNotNull); expect(content!.plainText, 'w are you?Good, an'); @@ -3233,8 +3397,8 @@ void main() { expect(paragraph1.selections.length, 1); expect(paragraph1.selections[0].start, 2); expect(paragraph1.selections[0].end, 7); - expect(paragraph2.selections.length, 0); - expect(paragraph3.selections.length, 0); + expect(paragraph2.selections.length, 1); + expect(paragraph3.selections.length, 1); expect(content, isNotNull); expect(content!.plainText, 'w are'); @@ -3243,8 +3407,8 @@ void main() { expect(paragraph1.selections.length, 1); expect(paragraph1.selections[0].start, 0); expect(paragraph1.selections[0].end, 2); - expect(paragraph2.selections.length, 0); - expect(paragraph3.selections.length, 0); + expect(paragraph2.selections.length, 1); + expect(paragraph3.selections.length, 1); expect(content, isNotNull); expect(content!.plainText, 'Ho'); }); diff --git a/packages/flutter/test/widgets/single_child_scroll_view_test.dart b/packages/flutter/test/widgets/single_child_scroll_view_test.dart index 2cc8708215436..dfe67d39ff20a 100644 --- a/packages/flutter/test/widgets/single_child_scroll_view_test.dart +++ b/packages/flutter/test/widgets/single_child_scroll_view_test.dart @@ -486,6 +486,40 @@ void main() { expect(semanticsClip.size.width, length); }); + testWidgetsWithLeakTracking('SingleChildScrollView getOffsetToReveal - will not assert on axis mismatch', (WidgetTester tester) async { + final ScrollController controller = ScrollController(initialScrollOffset: 300.0); + addTearDown(controller.dispose); + List children; + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + height: 200.0, + width: 300.0, + child: SingleChildScrollView( + controller: controller, + child: Column( + children: children = List.generate(20, (int i) { + return SizedBox( + height: 100.0, + width: 300.0, + child: Text('Tile $i'), + ); + }), + ), + ), + ), + ), + ), + ); + + final RenderAbstractViewport viewport = tester.allRenderObjects.whereType().first; + + final RenderObject target = tester.renderObject(find.byWidget(children[5])); + viewport.getOffsetToReveal(target, 0.0, axis: Axis.horizontal); + }); + testWidgetsWithLeakTracking('SingleChildScrollView getOffsetToReveal - down', (WidgetTester tester) async { final ScrollController controller = ScrollController(initialScrollOffset: 300.0); addTearDown(controller.dispose); diff --git a/packages/flutter/test/widgets/tracking_scroll_controller_test.dart b/packages/flutter/test/widgets/tracking_scroll_controller_test.dart index fd76a6d0c4daf..f554696b856b5 100644 --- a/packages/flutter/test/widgets/tracking_scroll_controller_test.dart +++ b/packages/flutter/test/widgets/tracking_scroll_controller_test.dart @@ -60,4 +60,43 @@ void main() { expect(controller.initialScrollOffset, 0.0); }); + + testWidgetsWithLeakTracking('TrackingScrollController saves offset', (WidgetTester tester) async { + int attach = 0; + int detach = 0; + final TrackingScrollController controller = TrackingScrollController( + onAttach: (_) { attach++; }, + onDetach: (_) { detach++; }, + ); + addTearDown(controller.dispose); + const double listItemHeight = 100.0; + + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: PageView.builder( + itemBuilder: (BuildContext context, int index) { + return ListView( + controller: controller, + children: List.generate( + 10, + (int i) => SizedBox( + height: listItemHeight, + child: Text('Page$index-Item$i'), + ), + ).toList(), + ); + }, + ), + )); + await tester.pumpAndSettle(); + + expect(attach, 1); + expect(detach, 0); + + await tester.pumpWidget(Container()); + await tester.pumpAndSettle(); + + expect(attach, 1); + expect(detach, 1); + }); } diff --git a/packages/flutter/test/widgets/transform_test.dart b/packages/flutter/test/widgets/transform_test.dart index 2165e0a8e1054..4accf2b495e10 100644 --- a/packages/flutter/test/widgets/transform_test.dart +++ b/packages/flutter/test/widgets/transform_test.dart @@ -13,10 +13,11 @@ import 'dart:ui' as ui; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'package:vector_math/vector_math_64.dart'; void main() { - testWidgets('Transform origin', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform origin', (WidgetTester tester) async { bool didReceiveTap = false; await tester.pumpWidget( Directionality( @@ -64,7 +65,7 @@ void main() { expect(didReceiveTap, isTrue); }); - testWidgets('Transform alignment', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform alignment', (WidgetTester tester) async { bool didReceiveTap = false; await tester.pumpWidget( Directionality( @@ -112,7 +113,7 @@ void main() { expect(didReceiveTap, isTrue); }); - testWidgets('Transform AlignmentDirectional alignment', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform AlignmentDirectional alignment', (WidgetTester tester) async { bool didReceiveTap = false; Widget buildFrame(TextDirection textDirection, AlignmentGeometry alignment) { @@ -183,7 +184,7 @@ void main() { expect(didReceiveTap, isTrue); }); - testWidgets('Transform offset + alignment', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform offset + alignment', (WidgetTester tester) async { bool didReceiveTap = false; await tester.pumpWidget( Directionality( @@ -232,7 +233,7 @@ void main() { expect(didReceiveTap, isTrue); }); - testWidgets('Composited transform offset', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Composited transform offset', (WidgetTester tester) async { await tester.pumpWidget( Center( child: SizedBox( @@ -261,7 +262,7 @@ void main() { expect(transform.getTranslation(), equals(Vector3(100.0, 75.0, 0.0))); }); - testWidgets('Transform.rotate', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform.rotate', (WidgetTester tester) async { await tester.pumpWidget( Transform.rotate( angle: math.pi / 2.0, @@ -283,7 +284,7 @@ void main() { ]); }); - testWidgets('applyPaintTransform of Transform in Padding', (WidgetTester tester) async { + testWidgetsWithLeakTracking('applyPaintTransform of Transform in Padding', (WidgetTester tester) async { await tester.pumpWidget( Padding( padding: const EdgeInsets.only( @@ -301,7 +302,7 @@ void main() { expect(tester.getTopLeft(find.byType(Placeholder)), const Offset(30.0, 20.0)); }); - testWidgets('Transform.translate', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform.translate', (WidgetTester tester) async { await tester.pumpWidget( Transform.translate( offset: const Offset(100.0, 50.0), @@ -316,7 +317,7 @@ void main() { expect(tester.getTopLeft(find.byType(Container)), const Offset(100.0, 50.0)); }); - testWidgets('Transform.scale', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform.scale', (WidgetTester tester) async { await tester.pumpWidget( Transform.scale( scale: 2.0, @@ -339,7 +340,7 @@ void main() { ]); }); - testWidgets('Transform with nan value short-circuits rendering', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform with nan value short-circuits rendering', (WidgetTester tester) async { await tester.pumpWidget( Transform( transform: Matrix4.identity() @@ -351,7 +352,7 @@ void main() { expect(tester.layers, hasLength(1)); }); - testWidgets('Transform with inf value short-circuits rendering', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform with inf value short-circuits rendering', (WidgetTester tester) async { await tester.pumpWidget( Transform( transform: Matrix4.identity() @@ -363,7 +364,7 @@ void main() { expect(tester.layers, hasLength(1)); }); - testWidgets('Transform with -inf value short-circuits rendering', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform with -inf value short-circuits rendering', (WidgetTester tester) async { await tester.pumpWidget( Transform( transform: Matrix4.identity() @@ -375,7 +376,7 @@ void main() { expect(tester.layers, hasLength(1)); }); - testWidgets('Transform.rotate does not remove layers due to singular short-circuit', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform.rotate does not remove layers due to singular short-circuit', (WidgetTester tester) async { await tester.pumpWidget( Transform.rotate( angle: math.pi / 2, @@ -386,7 +387,7 @@ void main() { expect(tester.layers, hasLength(3)); }); - testWidgets('Transform.rotate creates nice rotation matrices for 0, 90, 180, 270 degrees', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform.rotate creates nice rotation matrices for 0, 90, 180, 270 degrees', (WidgetTester tester) async { await tester.pumpWidget( Transform.rotate( angle: math.pi / 2, @@ -447,7 +448,7 @@ void main() { expect(tester.layers, hasLength(2)); }); - testWidgets('Transform.scale with 0.0 does not paint child layers', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform.scale with 0.0 does not paint child layers', (WidgetTester tester) async { await tester.pumpWidget( Transform.scale( scale: 0.0, @@ -486,7 +487,7 @@ void main() { }); - testWidgets('Translated child into translated box - hit test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Translated child into translated box - hit test', (WidgetTester tester) async { final GlobalKey key1 = GlobalKey(); bool pointerDown = false; await tester.pumpWidget( @@ -524,7 +525,7 @@ void main() { ); } - testWidgets( + testWidgetsWithLeakTracking( '3D transform renders the same with or without needsCompositing', (WidgetTester tester) async { for (double angle = 0; angle <= math.pi/4; angle += 0.01) { @@ -532,6 +533,7 @@ void main() { final RenderBox renderBox = tester.binding.renderView.child!; final OffsetLayer layer = renderBox.debugLayer! as OffsetLayer; final ui.Image imageWithCompositing = await layer.toImage(renderBox.paintBounds); + addTearDown(imageWithCompositing.dispose); await tester.pumpWidget(RepaintBoundary(child: generateTransform(false, angle))); await expectLater(find.byType(RepaintBoundary).first, matchesReferenceImage(imageWithCompositing)); @@ -545,7 +547,7 @@ void main() { return numbers.map((String str) => double.parse(str.trim())).toList(); } - testWidgets('Transform.translate with FilterQuality produces filter layer', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform.translate with FilterQuality produces filter layer', (WidgetTester tester) async { await tester.pumpWidget( Transform.translate( offset: const Offset(25.0, 25.0), @@ -563,7 +565,7 @@ void main() { ]); }); - testWidgets('Transform.scale with FilterQuality produces filter layer', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform.scale with FilterQuality produces filter layer', (WidgetTester tester) async { await tester.pumpWidget( Transform.scale( scale: 3.14159, @@ -581,7 +583,7 @@ void main() { ]); }); - testWidgets('Transform.rotate with FilterQuality produces filter layer', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform.rotate with FilterQuality produces filter layer', (WidgetTester tester) async { await tester.pumpWidget( Transform.rotate( angle: math.pi / 4, @@ -599,7 +601,7 @@ void main() { ]); }); - testWidgets('Offset Transform.rotate with FilterQuality produces filter layer', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Offset Transform.rotate with FilterQuality produces filter layer', (WidgetTester tester) async { await tester.pumpWidget( SizedBox(width: 400, height: 400, child: Center( @@ -621,7 +623,7 @@ void main() { ]); }); - testWidgets('Transform layers update to match child and filterQuality', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform layers update to match child and filterQuality', (WidgetTester tester) async { await tester.pumpWidget( Transform.rotate( angle: math.pi / 4, @@ -657,7 +659,7 @@ void main() { expect(tester.layers.whereType(), hasLength(1)); }); - testWidgets('Transform layers with filterQuality golden', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Transform layers with filterQuality golden', (WidgetTester tester) async { await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -701,7 +703,7 @@ void main() { ); }); - testWidgets("Transform.scale() does not accept all three 'scale', 'scaleX' and 'scaleY' parameters to be non-null", (WidgetTester tester) async { + testWidgetsWithLeakTracking("Transform.scale() does not accept all three 'scale', 'scaleX' and 'scaleY' parameters to be non-null", (WidgetTester tester) async { await expectLater(() { tester.pumpWidget(Directionality( textDirection: TextDirection.ltr, @@ -719,7 +721,7 @@ void main() { }, throwsAssertionError); }); - testWidgets("Transform.scale() needs at least one of 'scale', 'scaleX' and 'scaleY' to be non-null, otherwise throws AssertionError", (WidgetTester tester) async { + testWidgetsWithLeakTracking("Transform.scale() needs at least one of 'scale', 'scaleX' and 'scaleY' to be non-null, otherwise throws AssertionError", (WidgetTester tester) async { await expectLater(() { tester.pumpWidget(Directionality( textDirection: TextDirection.ltr, @@ -734,7 +736,7 @@ void main() { }, throwsAssertionError); }); - testWidgets("Transform.scale() scales widget uniformly with 'scale' parameter", (WidgetTester tester) async { + testWidgetsWithLeakTracking("Transform.scale() scales widget uniformly with 'scale' parameter", (WidgetTester tester) async { const double scale = 1.5; const double height = 100; const double width = 150; @@ -760,7 +762,7 @@ void main() { expect(tester.getBottomRight(find.byType(Container)), target.bottomRight(tester.getTopLeft(find.byType(Container)))); }); - testWidgets("Transform.scale() scales widget according to 'scaleX' and 'scaleY'", (WidgetTester tester) async { + testWidgetsWithLeakTracking("Transform.scale() scales widget according to 'scaleX' and 'scaleY'", (WidgetTester tester) async { const double scaleX = 1.5; const double scaleY = 1.2; const double height = 100; @@ -788,7 +790,7 @@ void main() { expect(tester.getBottomRight(find.byType(Container)), target.bottomRight(tester.getTopLeft(find.byType(Container)))); }); - testWidgets( + testWidgetsWithLeakTracking( 'Transform.flip does flip child correctly', (WidgetTester tester) async { const Offset topRight = Offset(60, 20); diff --git a/packages/flutter/test/widgets/two_dimensional_utils.dart b/packages/flutter/test/widgets/two_dimensional_utils.dart index d2cbf3b8883a7..a518f52170a13 100644 --- a/packages/flutter/test/widgets/two_dimensional_utils.dart +++ b/packages/flutter/test/widgets/two_dimensional_utils.dart @@ -17,6 +17,7 @@ final TwoDimensionalChildBuilderDelegate builderDelegate = TwoDimensionalChildBu maxYIndex: 5, builder: (BuildContext context, ChildVicinity vicinity) { return Container( + key: ValueKey(vicinity), color: vicinity.xIndex.isEven && vicinity.yIndex.isEven ? Colors.amber[100] : (vicinity.xIndex.isOdd && vicinity.yIndex.isOdd diff --git a/packages/flutter/test/widgets/two_dimensional_viewport_test.dart b/packages/flutter/test/widgets/two_dimensional_viewport_test.dart index 8063ea0d1a690..28f3bcac73bd0 100644 --- a/packages/flutter/test/widgets/two_dimensional_viewport_test.dart +++ b/packages/flutter/test/widgets/two_dimensional_viewport_test.dart @@ -1441,10 +1441,15 @@ void main() { // Horizontal mismatch expect( () { + final ViewportOffset verticalOffset = ViewportOffset.fixed(0.0); + addTearDown(verticalOffset.dispose); + final ViewportOffset horizontalOffset = ViewportOffset.fixed(0.0); + addTearDown(horizontalOffset.dispose); + SimpleBuilderTableViewport( - verticalOffset: ViewportOffset.fixed(0.0), + verticalOffset: verticalOffset, verticalAxisDirection: AxisDirection.left, - horizontalOffset: ViewportOffset.fixed(0.0), + horizontalOffset: horizontalOffset, horizontalAxisDirection: AxisDirection.right, delegate: builderDelegate, mainAxis: Axis.vertical, @@ -1462,10 +1467,15 @@ void main() { // Vertical mismatch expect( () { + final ViewportOffset verticalOffset = ViewportOffset.fixed(0.0); + addTearDown(verticalOffset.dispose); + final ViewportOffset horizontalOffset = ViewportOffset.fixed(0.0); + addTearDown(horizontalOffset.dispose); + SimpleBuilderTableViewport( - verticalOffset: ViewportOffset.fixed(0.0), + verticalOffset: verticalOffset, verticalAxisDirection: AxisDirection.up, - horizontalOffset: ViewportOffset.fixed(0.0), + horizontalOffset: horizontalOffset, horizontalAxisDirection: AxisDirection.down, delegate: builderDelegate, mainAxis: Axis.vertical, @@ -1483,10 +1493,15 @@ void main() { // Both expect( () { + final ViewportOffset verticalOffset = ViewportOffset.fixed(0.0); + addTearDown(verticalOffset.dispose); + final ViewportOffset horizontalOffset = ViewportOffset.fixed(0.0); + addTearDown(horizontalOffset.dispose); + SimpleBuilderTableViewport( - verticalOffset: ViewportOffset.fixed(0.0), + verticalOffset: verticalOffset, verticalAxisDirection: AxisDirection.left, - horizontalOffset: ViewportOffset.fixed(0.0), + horizontalOffset: horizontalOffset, horizontalAxisDirection: AxisDirection.down, delegate: builderDelegate, mainAxis: Axis.vertical, @@ -1548,10 +1563,15 @@ void main() { // Horizontal mismatch expect( () { + final ViewportOffset verticalOffset = ViewportOffset.fixed(0.0); + addTearDown(verticalOffset.dispose); + final ViewportOffset horizontalOffset = ViewportOffset.fixed(0.0); + addTearDown(horizontalOffset.dispose); + RenderSimpleBuilderTableViewport( - verticalOffset: ViewportOffset.fixed(0.0), + verticalOffset: verticalOffset, verticalAxisDirection: AxisDirection.left, - horizontalOffset: ViewportOffset.fixed(0.0), + horizontalOffset: horizontalOffset, horizontalAxisDirection: AxisDirection.right, delegate: builderDelegate, mainAxis: Axis.vertical, @@ -1570,10 +1590,15 @@ void main() { // Vertical mismatch expect( () { + final ViewportOffset verticalOffset = ViewportOffset.fixed(0.0); + addTearDown(verticalOffset.dispose); + final ViewportOffset horizontalOffset = ViewportOffset.fixed(0.0); + addTearDown(horizontalOffset.dispose); + RenderSimpleBuilderTableViewport( - verticalOffset: ViewportOffset.fixed(0.0), + verticalOffset: verticalOffset, verticalAxisDirection: AxisDirection.up, - horizontalOffset: ViewportOffset.fixed(0.0), + horizontalOffset: horizontalOffset, horizontalAxisDirection: AxisDirection.down, delegate: builderDelegate, mainAxis: Axis.vertical, @@ -1592,10 +1617,15 @@ void main() { // Both expect( () { + final ViewportOffset verticalOffset = ViewportOffset.fixed(0.0); + addTearDown(verticalOffset.dispose); + final ViewportOffset horizontalOffset = ViewportOffset.fixed(0.0); + addTearDown(horizontalOffset.dispose); + RenderSimpleBuilderTableViewport( - verticalOffset: ViewportOffset.fixed(0.0), + verticalOffset: verticalOffset, verticalAxisDirection: AxisDirection.left, - horizontalOffset: ViewportOffset.fixed(0.0), + horizontalOffset: horizontalOffset, horizontalAxisDirection: AxisDirection.down, delegate: builderDelegate, mainAxis: Axis.vertical, @@ -1622,10 +1652,15 @@ void main() { } ); addTearDown(delegate.dispose); + final ViewportOffset verticalOffset = ViewportOffset.fixed(10.0); + addTearDown(verticalOffset.dispose); + final ViewportOffset horizontalOffset = ViewportOffset.fixed(20.0); + addTearDown(horizontalOffset.dispose); + final RenderSimpleBuilderTableViewport renderViewport = RenderSimpleBuilderTableViewport( - verticalOffset: ViewportOffset.fixed(10.0), + verticalOffset: verticalOffset, verticalAxisDirection: AxisDirection.down, - horizontalOffset: ViewportOffset.fixed(20.0), + horizontalOffset: horizontalOffset, horizontalAxisDirection: AxisDirection.right, delegate: delegate, mainAxis: Axis.vertical, @@ -2365,6 +2400,317 @@ void main() { ), ); }, variant: TargetPlatformVariant.all()); + + group('showOnScreen & showInViewport', () { + Finder findKey(ChildVicinity vicinity) { + return find.byKey(ValueKey(vicinity)); + } + + testWidgets('getOffsetToReveal', (WidgetTester tester) async { + await tester.pumpWidget(simpleBuilderTest(useCacheExtent: true)); + + RenderAbstractViewport viewport = tester.allRenderObjects.whereType().first; + final RevealedOffset verticalOffset = viewport.getOffsetToReveal( + tester.renderObject(findKey(const ChildVicinity(xIndex: 5, yIndex: 5))), + 1.0, + axis: Axis.vertical, + ); + final RevealedOffset horizontalOffset = viewport.getOffsetToReveal( + tester.renderObject(findKey(const ChildVicinity(xIndex: 5, yIndex: 5))), + 1.0, + axis: Axis.horizontal, + ); + expect(verticalOffset.offset, 600.0); + expect(verticalOffset.rect, const Rect.fromLTRB(1000.0, 400.0, 1200.0, 600.0)); + expect(horizontalOffset.offset, 400.0); + expect(horizontalOffset.rect, const Rect.fromLTRB(600.0, 1000.0, 800.0, 1200.0)); + + // default is to use mainAxis when axis is not provided, mainAxis + // defaults to Axis.vertical. + RevealedOffset defaultOffset = viewport.getOffsetToReveal( + tester.renderObject(findKey(const ChildVicinity(xIndex: 5, yIndex: 5))), + 1.0, + ); + expect(defaultOffset.offset, verticalOffset.offset); + expect(defaultOffset.rect, verticalOffset.rect); + + // mainAxis as Axis.horizontal + await tester.pumpWidget(simpleBuilderTest( + useCacheExtent: true, + mainAxis: Axis.horizontal, + )); + viewport = tester.allRenderObjects.whereType().first; + defaultOffset = viewport.getOffsetToReveal( + tester.renderObject(findKey(const ChildVicinity(xIndex: 5, yIndex: 5))), + 1.0, + ); + expect(defaultOffset.offset, horizontalOffset.offset); + expect(defaultOffset.rect, horizontalOffset.rect); + }); + + testWidgets('Axis.vertical', (WidgetTester tester) async { + await tester.pumpWidget(simpleBuilderTest(useCacheExtent: true)); + // Child visible at origin + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 0))).dy, + equals(0.0), + ); + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 0, yIndex: 0)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 0))).dy, + equals(0.0), + ); + // (0, 3) is in the cache extent, and will be brought into view next + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 3))).dy, + equals(600.0), + ); + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 0, yIndex: 3)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + // Now in view + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 3))).dy, + equals(400.0), + ); + + // If already visible, no change + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 0, yIndex: 3)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 3))).dy, + equals(400.0), + ); + }); + + testWidgets('Axis.horizontal', (WidgetTester tester) async { + await tester.pumpWidget(simpleBuilderTest(useCacheExtent: true)); + + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 1, yIndex: 0)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 1, yIndex: 0))).dx, + equals(200.0), // No change since already fully visible + ); + // (5, 0) is now in the cache extent, and will be brought into view next + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 5, yIndex: 0))).dx, + equals(1000.0), + ); + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 5, yIndex: 0)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + // Now in view + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 5, yIndex: 0))).dx, + equals(600.0), + ); + + // If already in position, no change + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 5, yIndex: 0)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 5, yIndex: 0))).dx, + equals(600.0), + ); + }); + + testWidgets('both axes', (WidgetTester tester) async { + await tester.pumpWidget(simpleBuilderTest(useCacheExtent: true)); + + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 1, yIndex: 1)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 1, yIndex: 1))), + const Rect.fromLTRB(200.0, 200.0, 400.0, 400.0), + ); + // (5, 4) is in the cache extent, and will be brought into view next + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 5, yIndex: 4))), + const Rect.fromLTRB(1000.0, 800.0, 1200.0, 1000.0), + ); + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 5, yIndex: 4)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + // Now in view + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 5, yIndex: 4))), + const Rect.fromLTRB(600.0, 200.0, 800.0, 400.0), + ); + + // If already visible, no change + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 5, yIndex: 4)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 5, yIndex: 4))), + const Rect.fromLTRB(600.0, 200.0, 800.0, 400.0), + ); + }); + + testWidgets('Axis.vertical reverse', (WidgetTester tester) async { + await tester.pumpWidget(simpleBuilderTest( + verticalDetails: const ScrollableDetails.vertical(reverse: true), + useCacheExtent: true, + )); + + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 0))).dy, + equals(400.0), + ); + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 0, yIndex: 0)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + // Already visible so no change. + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 0))).dy, + equals(400.0), + ); + // (0, 3) is in the cache extent, and will be brought into view next + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 3))).dy, + equals(-200.0), + ); + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 0, yIndex: 3)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + // Now in view + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 3))).dy, + equals(0.0), + ); + + // If already visible, no change + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 0, yIndex: 3)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 3))).dy, + equals(0.0), + ); + }); + + testWidgets('Axis.horizontal reverse', (WidgetTester tester) async { + await tester.pumpWidget(simpleBuilderTest( + horizontalDetails: const ScrollableDetails.horizontal(reverse: true), + useCacheExtent: true, + )); + + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 0))).dx, + equals(600.0), + ); + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 0, yIndex: 0)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + // Already visible so no change. + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 0, yIndex: 0))).dx, + equals(600.0), + ); + // (4, 0) is in the cache extent, and will be brought into view next + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 4, yIndex: 0))).dx, + equals(-200.0), + ); + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 4, yIndex: 0)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 4, yIndex: 0))).dx, + equals(0.0), + ); + + // If already visible, no change + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 4, yIndex: 0)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + expect( + tester.getTopLeft(findKey(const ChildVicinity(xIndex: 4, yIndex: 0))).dx, + equals(0.0), + ); + }); + + testWidgets('both axes reverse', (WidgetTester tester) async { + await tester.pumpWidget(simpleBuilderTest( + verticalDetails: const ScrollableDetails.vertical(reverse: true), + horizontalDetails: const ScrollableDetails.horizontal(reverse: true), + useCacheExtent: true, + )); + + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 1, yIndex: 1)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 1, yIndex: 1))), + const Rect.fromLTRB(400.0, 200.0, 600.0, 400.0), + ); + // (5, 4) is in the cache extent, and will be brought into view next + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 5, yIndex: 4))), + const Rect.fromLTRB(-400.0, -400.0, -200.0, -200.0), + ); + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 5, yIndex: 4)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + // Now in view + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 5, yIndex: 4))), + const Rect.fromLTRB(0.0, 200.0, 200.0, 400.0), + ); + + // If already visible, no change + tester.renderObject(find.byKey( + const ValueKey(ChildVicinity(xIndex: 5, yIndex: 4)), + skipOffstage: false, + )).showOnScreen(); + await tester.pump(); + expect( + tester.getRect(findKey(const ChildVicinity(xIndex: 5, yIndex: 4))), + const Rect.fromLTRB(0.0, 200.0, 200.0, 400.0), + ); + }); + }); }); } diff --git a/packages/flutter/test/widgets/widget_inspector_test.dart b/packages/flutter/test/widgets/widget_inspector_test.dart index 29d6b33b36635..4d75cd78e4ff4 100644 --- a/packages/flutter/test/widgets/widget_inspector_test.dart +++ b/packages/flutter/test/widgets/widget_inspector_test.dart @@ -20,6 +20,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:leak_tracker/leak_tracker.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'widget_inspector_test_utils.dart'; @@ -317,7 +318,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(ref.target, null); }); - testWidgets('WidgetInspector smoke test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetInspector smoke test', (WidgetTester tester) async { // This is a smoke test to verify that adding the inspector doesn't crash. await tester.pumpWidget( const Directionality( @@ -351,7 +352,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(true, isTrue); // Expect that we reach here without crashing. }); - testWidgets('WidgetInspector interaction test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetInspector interaction test', (WidgetTester tester) async { final List log = []; final GlobalKey selectButtonKey = GlobalKey(); final GlobalKey inspectorKey = GlobalKey(); @@ -446,7 +447,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { ); }); - testWidgets('WidgetInspector non-invertible transform regression test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetInspector non-invertible transform regression test', (WidgetTester tester) async { await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -471,7 +472,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(true, isTrue); // Expect that we reach here without crashing. }); - testWidgets('WidgetInspector scroll test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetInspector scroll test', (WidgetTester tester) async { final Key childKey = UniqueKey(); final GlobalKey selectButtonKey = GlobalKey(); final GlobalKey inspectorKey = GlobalKey(); @@ -528,7 +529,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(0.0)); }); - testWidgets('WidgetInspector long press', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetInspector long press', (WidgetTester tester) async { bool didLongPress = false; await tester.pumpWidget( @@ -552,7 +553,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(didLongPress, isFalse); }); - testWidgets('WidgetInspector offstage', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetInspector offstage', (WidgetTester tester) async { final GlobalKey inspectorKey = GlobalKey(); final GlobalKey clickTarget = GlobalKey(); @@ -570,6 +571,14 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { ], ); } + + late final OverlayEntry entry1; + addTearDown(() => entry1..remove()..dispose()); + late final OverlayEntry entry2; + addTearDown(() => entry2..remove()..dispose()); + late final OverlayEntry entry3; + addTearDown(() => entry3..remove()..dispose()); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -578,16 +587,16 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { selectButtonBuilder: null, child: Overlay( initialEntries: [ - OverlayEntry( + entry1 = OverlayEntry( maintainState: true, builder: (BuildContext _) => createSubtree(width: 94.0), ), - OverlayEntry( + entry2 = OverlayEntry( opaque: true, maintainState: true, builder: (BuildContext _) => createSubtree(width: 95.0), ), - OverlayEntry( + entry3 = OverlayEntry( maintainState: true, builder: (BuildContext _) => createSubtree(width: 96.0, key: clickTarget), ), @@ -617,7 +626,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { ); }); - testWidgets('WidgetInspector with Transform above', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetInspector with Transform above', (WidgetTester tester) async { final GlobalKey childKey = GlobalKey(); final GlobalKey repaintBoundaryKey = GlobalKey(); @@ -664,7 +673,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { ); }); - testWidgets('Multiple widget inspectors', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Multiple widget inspectors', (WidgetTester tester) async { // This test verifies that interacting with different inspectors // works correctly. This use case may be an app that displays multiple // apps inside (i.e. a storyboard). @@ -826,7 +835,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { service.disposeGroup(group3); }); - testWidgets('WidgetInspectorService maybeSetSelection', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetInspectorService maybeSetSelection', (WidgetTester tester) async { await tester.pumpWidget( const Directionality( textDirection: TextDirection.ltr, @@ -873,7 +882,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(service.selection.currentElement, equals(elementA)); }); - testWidgets('WidgetInspectorService defunct selection regression test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetInspectorService defunct selection regression test', (WidgetTester tester) async { await tester.pumpWidget( const Directionality( textDirection: TextDirection.ltr, @@ -926,7 +935,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(service.selection.current, equals(null)); }); - testWidgets('WidgetInspectorService getParentChain', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetInspectorService getParentChain', (WidgetTester tester) async { const String group = 'test-group'; await tester.pumpWidget( @@ -994,7 +1003,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { } }); - testWidgets('WidgetInspectorService getChildren', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetInspectorService getChildren', (WidgetTester tester) async { const String group = 'test-group'; await tester.pumpWidget( @@ -1022,7 +1031,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { } }); - testWidgets('WidgetInspectorService creationLocation', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetInspectorService creationLocation', (WidgetTester tester) async { await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -1084,7 +1093,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(columnC, equals(19)); }, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag. - testWidgets('WidgetInspectorService setSelection notifiers for an Element', + testWidgetsWithLeakTracking('WidgetInspectorService setSelection notifiers for an Element', (WidgetTester tester) async { await tester.pumpWidget( const Directionality( @@ -1129,7 +1138,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { skip: !WidgetInspectorService.instance.isWidgetCreationTracked(), // [intended] Test requires --track-widget-creation flag. ); - testWidgets( + testWidgetsWithLeakTracking( 'WidgetInspectorService setSelection notifiers for a RenderObject', (WidgetTester tester) async { await tester.pumpWidget( @@ -1175,7 +1184,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { skip: !WidgetInspectorService.instance.isWidgetCreationTracked(), // [intended] Test requires --track-widget-creation flag. ); - testWidgets( + testWidgetsWithLeakTracking( 'WidgetInspector selectButton inspection for tap', (WidgetTester tester) async { final GlobalKey selectButtonKey = GlobalKey(); @@ -1225,7 +1234,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { skip: !WidgetInspectorService.instance.isWidgetCreationTracked() // [intended] Test requires --track-widget-creation flag. ); - testWidgets('test transformDebugCreator will re-order if after stack trace', (WidgetTester tester) async { + testWidgetsWithLeakTracking('test transformDebugCreator will re-order if after stack trace', (WidgetTester tester) async { final bool widgetTracked = WidgetInspectorService.instance.isWidgetCreationTracked(); await tester.pumpWidget( const Directionality( @@ -1289,7 +1298,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(nodes[4].runtimeType, DiagnosticsStackTrace); }); - testWidgets('test transformDebugCreator will not re-order if before stack trace', (WidgetTester tester) async { + testWidgetsWithLeakTracking('test transformDebugCreator will not re-order if before stack trace', (WidgetTester tester) async { final bool widgetTracked = WidgetInspectorService.instance.isWidgetCreationTracked(); await tester.pumpWidget( const Directionality( @@ -1352,7 +1361,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(nodes[4].runtimeType, DiagnosticsStackTrace); }, skip: WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --no-track-widget-creation flag. - testWidgets('test transformDebugCreator will add DevToolsDeepLinkProperty for overflow errors', (WidgetTester tester) async { + testWidgetsWithLeakTracking('test transformDebugCreator will add DevToolsDeepLinkProperty for overflow errors', (WidgetTester tester) async { activeDevToolsServerAddress = 'http://127.0.0.1:9100'; connectedVmServiceUri = 'http://127.0.0.1:55269/798ay5al_FM=/'; @@ -1387,7 +1396,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(nodes[5].runtimeType, StringProperty); }, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag. - testWidgets('test transformDebugCreator will not add DevToolsDeepLinkProperty for non-overflow errors', (WidgetTester tester) async { + testWidgetsWithLeakTracking('test transformDebugCreator will not add DevToolsDeepLinkProperty for non-overflow errors', (WidgetTester tester) async { activeDevToolsServerAddress = 'http://127.0.0.1:9100'; connectedVmServiceUri = 'http://127.0.0.1:55269/798ay5al_FM=/'; setupDefaultPubRootDirectory(service); @@ -1419,7 +1428,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(nodes[3].runtimeType, StringProperty); }, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag. - testWidgets('test transformDebugCreator will not add DevToolsDeepLinkProperty if devtoolsServerAddress is unavailable', (WidgetTester tester) async { + testWidgetsWithLeakTracking('test transformDebugCreator will not add DevToolsDeepLinkProperty if devtoolsServerAddress is unavailable', (WidgetTester tester) async { activeDevToolsServerAddress = null; connectedVmServiceUri = 'http://127.0.0.1:55269/798ay5al_FM=/'; setupDefaultPubRootDirectory(service); @@ -1561,7 +1570,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }); group('addPubRootDirectories', () { - testWidgets( + testWidgetsWithLeakTracking( 'does not have createdByLocalProject when there are no pubRootDirectories', (WidgetTester tester) async { const Widget widget = Directionality( @@ -1591,7 +1600,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'has createdByLocalProject when the element is part of the pubRootDirectory', (WidgetTester tester) async { const Widget widget = Directionality( @@ -1617,7 +1626,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'does not have createdByLocalProject when widget package directory is a suffix of a pubRootDirectory', (WidgetTester tester) async { const Widget widget = Directionality( @@ -1642,7 +1651,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'has createdByLocalProject when the pubRootDirectory is prefixed with file://', (WidgetTester tester) async { const Widget widget = Directionality( @@ -1667,7 +1676,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'does not have createdByLocalProject when thePubRootDirectory has a different suffix', (WidgetTester tester) async { const Widget widget = Directionality( @@ -1692,7 +1701,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'has createdByLocalProject even if another pubRootDirectory does not match', (WidgetTester tester) async { const Widget widget = Directionality( @@ -1720,7 +1729,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'widget is part of core framework and is the child of a widget in the package pubRootDirectories', (WidgetTester tester) async { const Widget widget = Directionality( @@ -1797,7 +1806,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { service.resetPubRootDirectories(); }); - testWidgets( + testWidgetsWithLeakTracking( 'reacts to add and removing pubRootDirectories', (WidgetTester tester) async { const Widget widget = Directionality( @@ -1835,7 +1844,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'does not match when the package directory does not match', (WidgetTester tester) async { const Widget widget = Directionality( @@ -1863,7 +1872,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'has createdByLocalProject when the pubRootDirectory is prefixed with file://', (WidgetTester tester) async { const Widget widget = Directionality( @@ -1888,7 +1897,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'can handle consecutive calls to add', (WidgetTester tester) async { const Widget widget = Directionality( @@ -1917,7 +1926,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { ); }, ); - testWidgets( + testWidgetsWithLeakTracking( 'can handle removing an unrelated pubRootDirectory', (WidgetTester tester) async { const Widget widget = Directionality( @@ -1953,7 +1962,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'can handle parent widget being part of a separate package', (WidgetTester tester) async { const Widget widget = Directionality( @@ -2030,7 +2039,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { ); group('InspectorSelection', () { - testWidgets('receives notifications when selection changes', + testWidgetsWithLeakTracking('receives notifications when selection changes', (WidgetTester tester) async { await tester.pumpWidget( const Directionality( @@ -2044,6 +2053,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { ), ); final InspectorSelection selection = InspectorSelection(); + addTearDown(selection.dispose); int count = 0; selection.addListener(() { count++; @@ -2124,7 +2134,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(() => service.toObject(aId), throwsFlutterError); }); - testWidgets('ext.flutter.inspector.setSelection', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.setSelection', (WidgetTester tester) async { await tester.pumpWidget( const Directionality( textDirection: TextDirection.ltr, @@ -2174,7 +2184,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(service.selection.currentElement, equals(elementA)); }); - testWidgets('ext.flutter.inspector.getParentChain', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.getParentChain', (WidgetTester tester) async { const String group = 'test-group'; await tester.pumpWidget( @@ -2246,7 +2256,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { } }); - testWidgets('ext.flutter.inspector.getChildren', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.getChildren', (WidgetTester tester) async { const String group = 'test-group'; await tester.pumpWidget( @@ -2276,7 +2286,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { } }); - testWidgets('ext.flutter.inspector.getChildrenDetailsSubtree', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.getChildrenDetailsSubtree', (WidgetTester tester) async { const String group = 'test-group'; await tester.pumpWidget( @@ -2315,7 +2325,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { } }); - testWidgets('WidgetInspectorService getDetailsSubtree', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetInspectorService getDetailsSubtree', (WidgetTester tester) async { const String group = 'test-group'; await tester.pumpWidget( @@ -2371,7 +2381,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { } }); - testWidgets('cyclic diagnostics regression test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('cyclic diagnostics regression test', (WidgetTester tester) async { const String group = 'test-group'; final CyclicDiagnostic a = CyclicDiagnostic('a'); final CyclicDiagnostic b = CyclicDiagnostic('b'); @@ -2407,7 +2417,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(nestedRelatedProperty, isNot(contains('children'))); }); - testWidgets('ext.flutter.inspector.getRootWidgetSummaryTree', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.getRootWidgetSummaryTree', (WidgetTester tester) async { const String group = 'test-group'; await tester.pumpWidget( const Directionality( @@ -2517,7 +2527,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(childJson['chidlren'], isNull); }, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag. - testWidgets('ext.flutter.inspector.getRootWidgetSummaryTreeWithPreviews', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.getRootWidgetSummaryTreeWithPreviews', (WidgetTester tester) async { const String group = 'test-group'; await tester.pumpWidget( @@ -2608,7 +2618,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(childJson['textPreview'], equals('c')); }, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag. - testWidgets('ext.flutter.inspector.getSelectedSummaryWidget', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.getSelectedSummaryWidget', (WidgetTester tester) async { const String group = 'test-group'; await tester.pumpWidget( @@ -2679,7 +2689,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(service.toObject(regularSelection['valueId']! as String), richTextDiagnostic.value); }, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag. - testWidgets('ext.flutter.inspector creationLocation', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector creationLocation', (WidgetTester tester) async { await tester.pumpWidget( const Directionality( textDirection: TextDirection.ltr, @@ -2741,7 +2751,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { service.resetPubRootDirectories(); }); - testWidgets( + testWidgetsWithLeakTracking( 'has createdByLocalProject when the widget is in the pubRootDirectory', (WidgetTester tester) async { await tester.pumpWidget( @@ -2774,7 +2784,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'does not have createdByLocalProject if the prefix of the pubRootDirectory is different', (WidgetTester tester) async { await tester.pumpWidget( @@ -2807,7 +2817,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'has createdByLocalProject if the pubRootDirectory is prefixed with file://', (WidgetTester tester) async { await tester.pumpWidget( @@ -2840,7 +2850,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'does not have createdByLocalProject if the pubRootDirectory has a different suffix', (WidgetTester tester) async { await tester.pumpWidget( @@ -2873,7 +2883,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'has createdByLocalProject if at least one of the pubRootDirectories matches', (WidgetTester tester) async { await tester.pumpWidget( @@ -2910,7 +2920,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'widget is part of core framework and is the child of a widget in the package pubRootDirectories', (WidgetTester tester) async { await tester.pumpWidget( @@ -3021,7 +3031,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { service.resetPubRootDirectories(); }); - testWidgets( + testWidgetsWithLeakTracking( 'has createdByLocalProject when the widget is in the pubRootDirectory', (WidgetTester tester) async { await tester.pumpWidget( @@ -3053,7 +3063,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'does not have createdByLocalProject if the prefix of the pubRootDirectory is different', (WidgetTester tester) async { await tester.pumpWidget( @@ -3088,7 +3098,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'has createdByLocalProject if the pubRootDirectory is prefixed with file://', (WidgetTester tester) async { await tester.pumpWidget( @@ -3120,7 +3130,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'does not have createdByLocalProject if the pubRootDirectory has a different suffix', (WidgetTester tester) async { await tester.pumpWidget( @@ -3155,7 +3165,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'has createdByLocalProject if at least one of the pubRootDirectories matches', (WidgetTester tester) async { await tester.pumpWidget( @@ -3213,7 +3223,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { service.resetPubRootDirectories(); }); - testWidgets( + testWidgetsWithLeakTracking( 'reacts to add and removing pubRootDirectories', (WidgetTester tester) async { const Widget widget = Directionality( @@ -3263,7 +3273,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'does not match when the package directory does not match', (WidgetTester tester) async { const Widget widget = Directionality( @@ -3297,7 +3307,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'has createdByLocalProject when the pubRootDirectory is prefixed with file://', (WidgetTester tester) async { const Widget widget = Directionality( @@ -3328,7 +3338,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'can handle consecutive calls to add', (WidgetTester tester) async { const Widget widget = Directionality( @@ -3362,7 +3372,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { ); }, ); - testWidgets( + testWidgetsWithLeakTracking( 'can handle removing an unrelated pubRootDirectory', (WidgetTester tester) async { const Widget widget = Directionality( @@ -3408,7 +3418,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'can handle parent widget being part of a separate package', (WidgetTester tester) async { const Widget widget = Directionality( @@ -3519,7 +3529,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { service.resetPubRootDirectories(); }); - testWidgets( + testWidgetsWithLeakTracking( 'reacts to add and removing pubRootDirectories', (WidgetTester tester) async { const Widget widget = Directionality( @@ -3571,7 +3581,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'does not match when the package directory does not match', (WidgetTester tester) async { const Widget widget = Directionality( @@ -3605,7 +3615,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'has createdByLocalProject when the pubRootDirectory is prefixed with file://', (WidgetTester tester) async { const Widget widget = Directionality( @@ -3639,7 +3649,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ); - testWidgets( + testWidgetsWithLeakTracking( 'can handle consecutive calls to add', (WidgetTester tester) async { const Widget widget = Directionality( @@ -3679,7 +3689,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { ); }, ); - testWidgets( + testWidgetsWithLeakTracking( 'can handle removing an unrelated pubRootDirectory', (WidgetTester tester) async { const Widget widget = Directionality( @@ -3738,7 +3748,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { skip: !WidgetInspectorService.instance.isWidgetCreationTracked(), // [intended] Test requires --track-widget-creation flag. ); - testWidgets('ext.flutter.inspector.trackRebuildDirtyWidgets with tear-offs', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.trackRebuildDirtyWidgets with tear-offs', (WidgetTester tester) async { final Widget widget = Directionality( textDirection: TextDirection.ltr, child: WidgetInspector( @@ -3760,7 +3770,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { skip: !WidgetInspectorService.instance.isWidgetCreationTracked(), // [intended] Test requires --track-widget-creation flag. ); - testWidgets('ext.flutter.inspector.trackRebuildDirtyWidgets', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.trackRebuildDirtyWidgets', (WidgetTester tester) async { service.rebuildCount = 0; await tester.pumpWidget(const ClockDemo()); @@ -3865,7 +3875,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { _CreationLocation location = knownLocations[id]!; expect(location.file, equals(file)); // ClockText widget. - expect(location.line, equals(56)); + expect(location.line, equals(57)); expect(location.column, equals(9)); expect(location.name, equals('ClockText')); expect(count, equals(1)); @@ -3875,7 +3885,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { location = knownLocations[id]!; expect(location.file, equals(file)); // Text widget in _ClockTextState build method. - expect(location.line, equals(94)); + expect(location.line, equals(95)); expect(location.column, equals(12)); expect(location.name, equals('Text')); expect(count, equals(1)); @@ -3902,7 +3912,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { location = knownLocations[id]!; expect(location.file, equals(file)); // ClockText widget. - expect(location.line, equals(56)); + expect(location.line, equals(57)); expect(location.column, equals(9)); expect(location.name, equals('ClockText')); expect(count, equals(3)); // 3 clock widget instances rebuilt. @@ -3912,7 +3922,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { location = knownLocations[id]!; expect(location.file, equals(file)); // Text widget in _ClockTextState build method. - expect(location.line, equals(94)); + expect(location.line, equals(95)); expect(location.column, equals(12)); expect(location.name, equals('Text')); expect(count, equals(3)); // 3 clock widget instances rebuilt. @@ -3979,7 +3989,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(rebuildEvents, isEmpty); }, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag. - testWidgets('ext.flutter.inspector.trackRepaintWidgets', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.trackRepaintWidgets', (WidgetTester tester) async { service.rebuildCount = 0; await tester.pumpWidget(const ClockDemo()); @@ -4102,7 +4112,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(repaintEvents, isEmpty); }, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag. - testWidgets('ext.flutter.inspector.show', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.show', (WidgetTester tester) async { final Iterable> extensionChangedEvents = service.getServiceExtensionStateChangedEvents('ext.flutter.inspector.show'); Map extensionChangedEvent; @@ -4164,7 +4174,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(WidgetsApp.debugShowWidgetInspectorOverride, isFalse); }); - testWidgets('ext.flutter.inspector.screenshot', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.screenshot', (WidgetTester tester) async { final GlobalKey outerContainerKey = GlobalKey(); final GlobalKey paddingKey = GlobalKey(); final GlobalKey redContainerKey = GlobalKey(); @@ -4230,26 +4240,38 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { final OffsetLayer layer = renderObject.debugLayer! as OffsetLayer; final int expectedChildLayerCount = getChildLayerCount(layer); expect(expectedChildLayerCount, equals(2)); + + final ui.Image image1 = await layer.toImage( + renderObject.semanticBounds.inflate(50.0), + ); + addTearDown(image1.dispose); + await expectLater( - layer.toImage(renderObject.semanticBounds.inflate(50.0)), + image1, matchesGoldenFile('inspector.repaint_boundary_margin.png'), ); // Regression test for how rendering with a pixel scale other than 1.0 // was handled. + final ui.Image image2 = await layer.toImage( + renderObject.semanticBounds.inflate(50.0), + pixelRatio: 0.5, + ); + addTearDown(image2.dispose); + await expectLater( - layer.toImage( - renderObject.semanticBounds.inflate(50.0), - pixelRatio: 0.5, - ), + image2, matchesGoldenFile('inspector.repaint_boundary_margin_small.png'), ); + final ui.Image image3 = await layer.toImage( + renderObject.semanticBounds.inflate(50.0), + pixelRatio: 2.0, + ); + addTearDown(image3.dispose); + await expectLater( - layer.toImage( - renderObject.semanticBounds.inflate(50.0), - pixelRatio: 2.0, - ), + image3, matchesGoldenFile('inspector.repaint_boundary_margin_large.png'), ); @@ -4259,12 +4281,15 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(layerParent, isNotNull); expect(firstChild, isNotNull); + final ui.Image? screenshot1 = await service.screenshot( + repaintBoundary, + width: 300.0, + height: 300.0, + ); + addTearDown(() => screenshot1?.dispose()); + await expectLater( - service.screenshot( - repaintBoundary, - width: 300.0, - height: 300.0, - ), + screenshot1, matchesGoldenFile('inspector.repaint_boundary.png'), ); @@ -4275,13 +4300,16 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { // of the layer. expect(getChildLayerCount(layer), equals(expectedChildLayerCount)); + final ui.Image? screenshot2 = await service.screenshot( + repaintBoundary, + width: 500.0, + height: 500.0, + margin: 50.0, + ); + addTearDown(() => screenshot2?.dispose()); + await expectLater( - service.screenshot( - repaintBoundary, - width: 500.0, - height: 500.0, - margin: 50.0, - ), + screenshot2, matchesGoldenFile('inspector.repaint_boundary_margin.png'), ); @@ -4295,13 +4323,16 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { // Make sure taking a screenshot didn't change the parent of the layer. expect(layer.parent, equals(layerParent)); + final ui.Image? screenshot3 = await service.screenshot( + repaintBoundary, + width: 300.0, + height: 300.0, + debugPaint: true, + ); + addTearDown(() => screenshot3?.dispose()); + await expectLater( - service.screenshot( - repaintBoundary, - width: 300.0, - height: 300.0, - debugPaint: true, - ), + screenshot3, matchesGoldenFile('inspector.repaint_boundary_debugPaint.png'), ); // Verify that taking a screenshot with debug paint on did not change @@ -4319,22 +4350,28 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(layer.attached, isTrue); // Full size image + final ui.Image? screenshot4 = await service.screenshot( + find.byKey(outerContainerKey).evaluate().single, + width: 100.0, + height: 100.0, + ); + addTearDown(() => screenshot4?.dispose()); + await expectLater( - service.screenshot( - find.byKey(outerContainerKey).evaluate().single, - width: 100.0, - height: 100.0, - ), + screenshot4, matchesGoldenFile('inspector.container.png'), ); + final ui.Image? screenshot5 = await service.screenshot( + find.byKey(outerContainerKey).evaluate().single, + width: 100.0, + height: 100.0, + debugPaint: true, + ); + addTearDown(() => screenshot5?.dispose()); + await expectLater( - service.screenshot( - find.byKey(outerContainerKey).evaluate().single, - width: 100.0, - height: 100.0, - debugPaint: true, - ), + screenshot5, matchesGoldenFile('inspector.container_debugPaint.png'), ); @@ -4348,59 +4385,73 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { ..markNeedsPaint(); expect(container.debugNeedsLayout, isTrue); + final ui.Image? screenshot6 = await service.screenshot( + find.byKey(outerContainerKey).evaluate().single, + width: 100.0, + height: 100.0, + debugPaint: true, + ); + addTearDown(() => screenshot6?.dispose()); + await expectLater( - service.screenshot( - find.byKey(outerContainerKey).evaluate().single, - width: 100.0, - height: 100.0, - debugPaint: true, - ), + screenshot6, matchesGoldenFile('inspector.container_debugPaint.png'), ); expect(container.debugNeedsLayout, isFalse); } // Small image + final ui.Image? screenshot7 = await service.screenshot( + find.byKey(outerContainerKey).evaluate().single, + width: 50.0, + height: 100.0, + ); + addTearDown(() => screenshot7?.dispose()); + await expectLater( - service.screenshot( - find.byKey(outerContainerKey).evaluate().single, - width: 50.0, - height: 100.0, - ), + screenshot7, matchesGoldenFile('inspector.container_small.png'), ); + final ui.Image? screenshot8 = await service.screenshot( + find.byKey(outerContainerKey).evaluate().single, + width: 400.0, + height: 400.0, + maxPixelRatio: 3.0, + ); + addTearDown(() => screenshot8?.dispose()); + await expectLater( - service.screenshot( - find.byKey(outerContainerKey).evaluate().single, - width: 400.0, - height: 400.0, - maxPixelRatio: 3.0, - ), + screenshot8, matchesGoldenFile('inspector.container_large.png'), ); // This screenshot will show the clip rect debug paint but no other // debug paint. + final ui.Image? screenshot9 = await service.screenshot( + find.byType(ClipRRect).evaluate().single, + width: 100.0, + height: 100.0, + debugPaint: true, + ); + addTearDown(() => screenshot9?.dispose()); + await expectLater( - service.screenshot( - find.byType(ClipRRect).evaluate().single, - width: 100.0, - height: 100.0, - debugPaint: true, - ), + screenshot9, matchesGoldenFile('inspector.clipRect_debugPaint.png'), ); final Element clipRect = find.byType(ClipRRect).evaluate().single; - final Future clipRectScreenshot = service.screenshot( + final ui.Image? clipRectScreenshot = await service.screenshot( clipRect, width: 100.0, height: 100.0, margin: 20.0, debugPaint: true, ); + addTearDown(() => clipRectScreenshot?.dispose()); + // Add a margin so that the clip icon shows up in the screenshot. // This golden image is platform dependent due to the clip icon. await expectLater( @@ -4428,43 +4479,53 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { final ui.FrameInfo frame = await codec.getNextFrame(); return frame.image; }))!; + addTearDown(screenshotImage.dispose); await expectLater( screenshotImage, - matchesReferenceImage((await clipRectScreenshot)!), + matchesReferenceImage(clipRectScreenshot!), ); // Test with a very visible debug paint + final ui.Image? screenshot10 = await service.screenshot( + find.byKey(paddingKey).evaluate().single, + width: 300.0, + height: 300.0, + debugPaint: true, + ); + addTearDown(() => screenshot10?.dispose()); + await expectLater( - service.screenshot( - find.byKey(paddingKey).evaluate().single, - width: 300.0, - height: 300.0, - debugPaint: true, - ), + screenshot10, matchesGoldenFile('inspector.padding_debugPaint.png'), ); // The bounds for this box crop its rendered content. + final ui.Image? screenshot11 = await service.screenshot( + find.byKey(sizedBoxKey).evaluate().single, + width: 300.0, + height: 300.0, + debugPaint: true, + ); + addTearDown(() => screenshot11?.dispose()); + await expectLater( - service.screenshot( - find.byKey(sizedBoxKey).evaluate().single, - width: 300.0, - height: 300.0, - debugPaint: true, - ), + screenshot11, matchesGoldenFile('inspector.sizedBox_debugPaint.png'), ); // Verify that setting a margin includes the previously cropped content. + final ui.Image? screenshot12 = await service.screenshot( + find.byKey(sizedBoxKey).evaluate().single, + width: 300.0, + height: 300.0, + margin: 50.0, + debugPaint: true, + ); + addTearDown(() => screenshot12?.dispose()); + await expectLater( - service.screenshot( - find.byKey(sizedBoxKey).evaluate().single, - width: 300.0, - height: 300.0, - margin: 50.0, - debugPaint: true, - ), + screenshot12, matchesGoldenFile('inspector.sizedBox_debugPaint_margin.png'), ); }); @@ -4496,7 +4557,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { await tester.pumpWidget(widget); } - testWidgets('ext.flutter.inspector.getLayoutExplorerNode for RenderBox with BoxParentData',(WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.getLayoutExplorerNode for RenderBox with BoxParentData',(WidgetTester tester) async { await pumpWidgetForLayoutExplorer(tester); final Element rowElement = tester.element(find.byType(Row)); @@ -4541,7 +4602,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(parentData['offsetY'], equals('293.0')); }); - testWidgets('ext.flutter.inspector.getLayoutExplorerNode for RenderBox with FlexParentData',(WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.getLayoutExplorerNode for RenderBox with FlexParentData',(WidgetTester tester) async { await pumpWidgetForLayoutExplorer(tester); final Element flexibleElement = tester.element(find.byType(Flexible).first); @@ -4583,7 +4644,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(result['parentData'], isNull); }); - testWidgets('ext.flutter.inspector.getLayoutExplorerNode for RenderView',(WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.getLayoutExplorerNode for RenderView',(WidgetTester tester) async { await pumpWidgetForLayoutExplorer(tester); final Element element = tester.element(find.byType(Directionality).first); @@ -4619,7 +4680,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(result['parentData'], isNull); }); - testWidgets('ext.flutter.inspector.setFlexFit', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.setFlexFit', (WidgetTester tester) async { await pumpWidgetForLayoutExplorer(tester); final Element childElement = tester.element(find.byType(Flexible).first); @@ -4649,7 +4710,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(result['flexFit'], equals('tight')); }); - testWidgets('ext.flutter.inspector.setFlexFactor', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.setFlexFactor', (WidgetTester tester) async { await pumpWidgetForLayoutExplorer(tester); final Element childElement = tester.element(find.byType(Flexible).first); @@ -4679,7 +4740,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(result['flexFactor'], equals(3)); }); - testWidgets('ext.flutter.inspector.setFlexProperties', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.setFlexProperties', (WidgetTester tester) async { await pumpWidgetForLayoutExplorer(tester); final Element rowElement = tester.element(find.byType(Row).first); @@ -4742,7 +4803,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(crossAxisAlignment, equals('start')); }); - testWidgets('ext.flutter.inspector.getLayoutExplorerNode does not throw StackOverflowError',(WidgetTester tester) async { + testWidgetsWithLeakTracking('ext.flutter.inspector.getLayoutExplorerNode does not throw StackOverflowError',(WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/115228 const Key leafKey = ValueKey('ColoredBox'); await tester.pumpWidget( @@ -4772,7 +4833,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(error, isNull); }); - testWidgets( + testWidgetsWithLeakTracking( 'ext.flutter.inspector.getLayoutExplorerNode, on a ToolTip, does not throw StackOverflowError', (WidgetTester tester) async { // Regression test for https://github.com/flutter/devtools/issues/5946 @@ -4904,7 +4965,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { } }); - testWidgets('Screenshot of composited transforms - only offsets', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Screenshot of composited transforms - only offsets', (WidgetTester tester) async { // Composited transforms are challenging to take screenshots of as the // LeaderLayer and FollowerLayer classes used by CompositedTransformTarget // and CompositedTransformFollower depend on traversing ancestors of the @@ -4974,31 +5035,44 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { matchesGoldenFile('inspector.composited_transform.only_offsets.png'), ); + final ui.Image? screenshot1 = await WidgetInspectorService.instance.screenshot( + find.byKey(stackWithTransformFollower).evaluate().first, + width: 5000.0, + height: 500.0, + ); + addTearDown(() => screenshot1?.dispose()); + await expectLater( - WidgetInspectorService.instance.screenshot( - find.byKey(stackWithTransformFollower).evaluate().first, - width: 5000.0, - height: 500.0, - ), + screenshot1, matchesGoldenFile('inspector.composited_transform.only_offsets_follower.png'), ); + final ui.Image? screenshot2 = await WidgetInspectorService.instance.screenshot( + find.byType(Stack).evaluate().first, + width: 300.0, + height: 300.0, + ); + addTearDown(() => screenshot2?.dispose()); + await expectLater( - WidgetInspectorService.instance.screenshot(find.byType(Stack).evaluate().first, width: 300.0, height: 300.0), + screenshot2, matchesGoldenFile('inspector.composited_transform.only_offsets_small.png'), ); + final ui.Image? screenshot3 = await WidgetInspectorService.instance.screenshot( + find.byKey(transformTargetParent).evaluate().first, + width: 500.0, + height: 500.0, + ); + addTearDown(() => screenshot3?.dispose()); + await expectLater( - WidgetInspectorService.instance.screenshot( - find.byKey(transformTargetParent).evaluate().first, - width: 500.0, - height: 500.0, - ), + screenshot3, matchesGoldenFile('inspector.composited_transform.only_offsets_target.png'), ); }); - testWidgets('Screenshot composited transforms - with rotations', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Screenshot composited transforms - with rotations', (WidgetTester tester) async { final LayerLink link = LayerLink(); final GlobalKey key1 = GlobalKey(); final GlobalKey key2 = GlobalKey(); @@ -5069,30 +5143,39 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { matchesGoldenFile('inspector.composited_transform.with_rotations.png'), ); + final ui.Image? screenshot1 = await WidgetInspectorService.instance.screenshot( + find.byKey(mainStackKey).evaluate().first, + width: 500.0, + height: 500.0, + ); + addTearDown(() => screenshot1?.dispose()); + await expectLater( - WidgetInspectorService.instance.screenshot( - find.byKey(mainStackKey).evaluate().first, - width: 500.0, - height: 500.0, - ), + screenshot1, matchesGoldenFile('inspector.composited_transform.with_rotations_small.png'), ); + final ui.Image? screenshot2 = await WidgetInspectorService.instance.screenshot( + find.byKey(stackWithTransformTarget).evaluate().first, + width: 500.0, + height: 500.0, + ); + addTearDown(() => screenshot2?.dispose()); + await expectLater( - WidgetInspectorService.instance.screenshot( - find.byKey(stackWithTransformTarget).evaluate().first, - width: 500.0, - height: 500.0, - ), + screenshot2, matchesGoldenFile('inspector.composited_transform.with_rotations_target.png'), ); + final ui.Image? screenshot3 = await WidgetInspectorService.instance.screenshot( + find.byKey(stackWithTransformFollower).evaluate().first, + width: 500.0, + height: 500.0, + ); + addTearDown(() => screenshot3?.dispose()); + await expectLater( - WidgetInspectorService.instance.screenshot( - find.byKey(stackWithTransformFollower).evaluate().first, - width: 500.0, - height: 500.0, - ), + screenshot3, matchesGoldenFile('inspector.composited_transform.with_rotations_follower.png'), ); @@ -5104,7 +5187,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(box2.localToGlobal(Offset.zero), equals(position2)); }); - testWidgets('getChildrenDetailsSubtree', (WidgetTester tester) async { + testWidgetsWithLeakTracking('getChildrenDetailsSubtree', (WidgetTester tester) async { await tester.pumpWidget( MaterialApp( title: 'Hello, World', @@ -5164,7 +5247,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(appBars.single, isNot(contains('children'))); }, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag. - testWidgets('InspectorSerializationDelegate addAdditionalPropertiesCallback', (WidgetTester tester) async { + testWidgetsWithLeakTracking('InspectorSerializationDelegate addAdditionalPropertiesCallback', (WidgetTester tester) async { await tester.pumpWidget( MaterialApp( title: 'Hello World!', @@ -5233,7 +5316,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(node.toJsonMap(emptyDelegate), node.toJsonMap(defaultDelegate)); }); - testWidgets('debugIsLocalCreationLocation test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('debugIsLocalCreationLocation test', (WidgetTester tester) async { setupDefaultPubRootDirectory(service); final GlobalKey key = GlobalKey(); @@ -5262,7 +5345,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(debugIsLocalCreationLocation(paddingElement.widget), isFalse); }, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag. - testWidgets('debugIsWidgetLocalCreation test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('debugIsWidgetLocalCreation test', (WidgetTester tester) async { setupDefaultPubRootDirectory(service); final GlobalKey key = GlobalKey(); @@ -5285,7 +5368,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(debugIsWidgetLocalCreation(paddingElement.widget), isFalse); }, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag. - testWidgets('debugIsWidgetLocalCreation false test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('debugIsWidgetLocalCreation false test', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); await tester.pumpWidget( diff --git a/packages/flutter/test_private/test/pubspec.yaml b/packages/flutter/test_private/test/pubspec.yaml index 19b76362958a8..328072b59b5a2 100644 --- a/packages/flutter/test_private/test/pubspec.yaml +++ b/packages/flutter/test_private/test/pubspec.yaml @@ -28,7 +28,7 @@ dependencies: string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_goldens: @@ -39,4 +39,4 @@ dev_dependencies: platform: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" process: 4.2.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: b866 +# PUBSPEC CHECKSUM: c367 diff --git a/packages/flutter_driver/pubspec.yaml b/packages/flutter_driver/pubspec.yaml index 77abc24a0659b..4a61caab07992 100644 --- a/packages/flutter_driver/pubspec.yaml +++ b/packages/flutter_driver/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: path: 1.8.3 meta: 1.10.0 vm_service: 11.10.0 - webdriver: 3.0.2 + webdriver: 3.0.3 async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -35,7 +35,7 @@ dependencies: term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: fake_async: 1.3.1 @@ -72,4 +72,4 @@ dev_dependencies: webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: bac0 +# PUBSPEC CHECKSUM: c9c2 diff --git a/packages/flutter_goldens/pubspec.yaml b/packages/flutter_goldens/pubspec.yaml index ad7f98079dc1c..d23c8e7b0f361 100644 --- a/packages/flutter_goldens/pubspec.yaml +++ b/packages/flutter_goldens/pubspec.yaml @@ -34,6 +34,6 @@ dependencies: test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 3ac7 +# PUBSPEC CHECKSUM: 45c8 diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_af.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_af.arb index 8a689cc1deee5..e686fe0c9470c 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_af.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_af.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Soek", "noSpellCheckReplacementsLabel": "Geen plaasvervangers gevind nie", "menuDismissLabel": "Maak kieslys toe", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Kyk op", + "searchWebButtonLabel": "Deursoek web", + "shareButtonLabel": "Deel …" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_am.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_am.arb index e2075ff897e2b..248496666bef8 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_am.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_am.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "ፍለጋ", "noSpellCheckReplacementsLabel": "ምንም ተተኪዎች አልተገኙም", "menuDismissLabel": "ምናሌን አሰናብት", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "ይመልከቱ", + "searchWebButtonLabel": "ድርን ፈልግ", + "shareButtonLabel": "አጋራ..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_ar.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_ar.arb index dbe42013b85bc..7bdfeb4ce25e9 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_ar.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_ar.arb @@ -44,7 +44,7 @@ "searchTextFieldPlaceholderLabel": "بحث", "noSpellCheckReplacementsLabel": "لم يتم العثور على بدائل", "menuDismissLabel": "إغلاق القائمة", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "النظر إلى أعلى", + "searchWebButtonLabel": "البحث على الويب", + "shareButtonLabel": "مشاركة…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_as.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_as.arb index 18770258b9084..34ecac02a57ee 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_as.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_as.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "সন্ধান কৰক", "noSpellCheckReplacementsLabel": "এইটোৰ সলনি ব্যৱহাৰ কৰিব পৰা শব্দ পোৱা নগ’ল", "menuDismissLabel": "অগ্ৰাহ্য কৰাৰ মেনু", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "ওপৰলৈ চাওক", + "searchWebButtonLabel": "ৱেবত সন্ধান কৰক", + "shareButtonLabel": "শ্বেয়াৰ কৰক…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_az.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_az.arb index bef3e1de9a87c..69cb483e5c787 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_az.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_az.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Axtarın", "noSpellCheckReplacementsLabel": "Əvəzləmə Tapılmadı", "menuDismissLabel": "Menyunu qapadın", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Axtarın", + "searchWebButtonLabel": "Vebdə axtarın", + "shareButtonLabel": "Paylaşın..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_be.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_be.arb index da1534cf8dcfe..8fc71c7fa25b9 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_be.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_be.arb @@ -34,7 +34,7 @@ "searchTextFieldPlaceholderLabel": "Пошук", "noSpellCheckReplacementsLabel": "Замен не знойдзена", "menuDismissLabel": "Закрыць меню", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Знайсці", + "searchWebButtonLabel": "Пошук у сетцы", + "shareButtonLabel": "Абагуліць..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_bg.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_bg.arb index 8c727de43f2fb..0880a47a4bc12 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_bg.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_bg.arb @@ -25,6 +25,6 @@ "noSpellCheckReplacementsLabel": "Не бяха намерени замествания", "menuDismissLabel": "Отхвърляне на менюто", "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Търсене в мрежата", + "shareButtonLabel": "Споделяне..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_bn.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_bn.arb index df1afd72b0462..ff192a3d9d9ec 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_bn.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_bn.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "সার্চ করুন", "noSpellCheckReplacementsLabel": "কোনও বিকল্প বানান দেখানো হয়নি", "menuDismissLabel": "বাতিল করার মেনু", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "লুক-আপ", + "searchWebButtonLabel": "ওয়েবে সার্চ করুন", + "shareButtonLabel": "শেয়ার করুন..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_bs.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_bs.arb index 12f25c219eb56..f5f799896f741 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_bs.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_bs.arb @@ -29,7 +29,7 @@ "searchTextFieldPlaceholderLabel": "Pretraživanje", "noSpellCheckReplacementsLabel": "Nije pronađena nijedna zamjena", "menuDismissLabel": "Odbacivanje menija", - "lookUpButtonLabel": "Pogled prema gore", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Pogled nagore", + "searchWebButtonLabel": "Pretraži Web", + "shareButtonLabel": "Dijeli..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_ca.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_ca.arb index e11eb138abc82..e18684882bd20 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_ca.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_ca.arb @@ -18,13 +18,13 @@ "cutButtonLabel": "Retalla", "copyButtonLabel": "Copia", "pasteButtonLabel": "Enganxa", - "selectAllButtonLabel": "Selecciona-ho tot", + "selectAllButtonLabel": "Seleccionar-ho tot", "tabSemanticsLabel": "Pestanya $tabIndex de $tabCount", "modalBarrierDismissLabel": "Ignora", "searchTextFieldPlaceholderLabel": "Cerca", "noSpellCheckReplacementsLabel": "No s'ha trobat cap substitució", "menuDismissLabel": "Ignora el menú", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Mira amunt", + "searchWebButtonLabel": "Cerca al web", + "shareButtonLabel": "Comparteix..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_cs.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_cs.arb index de7c1b5d53456..fa6dfec2b96e7 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_cs.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_cs.arb @@ -34,7 +34,7 @@ "searchTextFieldPlaceholderLabel": "Hledat", "noSpellCheckReplacementsLabel": "Žádná nahrazení nenalezena", "menuDismissLabel": "Zavřít nabídku", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Vyhledat", + "searchWebButtonLabel": "Vyhledávat na webu", + "shareButtonLabel": "Sdílet…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_cy.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_cy.arb index 90a118f4298dd..3fdb1a873e81a 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_cy.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_cy.arb @@ -44,7 +44,7 @@ "modalBarrierDismissLabel": "Diystyru", "noSpellCheckReplacementsLabel": "Dim Ailosodiadau wedi'u Canfod", "menuDismissLabel": "Diystyru'r ddewislen", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Chwilio", + "searchWebButtonLabel": "Chwilio'r We", + "shareButtonLabel": "Rhannu..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_da.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_da.arb index 29b7d4a691cdb..78419f9a2b467 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_da.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_da.arb @@ -18,13 +18,13 @@ "cutButtonLabel": "Klip", "copyButtonLabel": "Kopiér", "pasteButtonLabel": "Indsæt", - "selectAllButtonLabel": "Vælg alle", + "selectAllButtonLabel": "Vælg alt", "tabSemanticsLabel": "Fane $tabIndex af $tabCount", "modalBarrierDismissLabel": "Afvis", "searchTextFieldPlaceholderLabel": "Søg", "noSpellCheckReplacementsLabel": "Der blev ikke fundet nogen erstatninger", "menuDismissLabel": "Luk menu", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Slå op", + "searchWebButtonLabel": "Søg på nettet", + "shareButtonLabel": "Del…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_de.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_de.arb index 5eeefca1c7857..2b3dc4bc9642c 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_de.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_de.arb @@ -18,13 +18,13 @@ "cutButtonLabel": "Ausschneiden", "copyButtonLabel": "Kopieren", "pasteButtonLabel": "Einsetzen", - "selectAllButtonLabel": "Alles auswählen", + "selectAllButtonLabel": "Alle auswählen", "tabSemanticsLabel": "Tab $tabIndex von $tabCount", "modalBarrierDismissLabel": "Schließen", "searchTextFieldPlaceholderLabel": "Suche", "noSpellCheckReplacementsLabel": "Keine Ersetzungen gefunden", "menuDismissLabel": "Menü schließen", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Nachschlagen", + "searchWebButtonLabel": "Im Web suchen", + "shareButtonLabel": "Teilen…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_el.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_el.arb index af1ee5a8bf999..81ec9991d6c07 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_el.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_el.arb @@ -25,6 +25,6 @@ "noSpellCheckReplacementsLabel": "Δεν βρέθηκαν αντικαταστάσεις", "menuDismissLabel": "Παράβλεψη μενού", "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Αναζήτηση στον ιστό", + "shareButtonLabel": "Κοινοποίηση…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_en_AU.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_en_AU.arb index c0780fe62b876..fc2b48b92e57f 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_en_AU.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_en_AU.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "lookUpButtonLabel": "Look up", "noSpellCheckReplacementsLabel": "No replacements found", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_en_GB.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_en_GB.arb index c0780fe62b876..fc2b48b92e57f 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_en_GB.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_en_GB.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "lookUpButtonLabel": "Look up", "noSpellCheckReplacementsLabel": "No replacements found", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_en_IE.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_en_IE.arb index c0780fe62b876..fc2b48b92e57f 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_en_IE.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_en_IE.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "lookUpButtonLabel": "Look up", "noSpellCheckReplacementsLabel": "No replacements found", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_en_IN.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_en_IN.arb index c0780fe62b876..fc2b48b92e57f 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_en_IN.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_en_IN.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "lookUpButtonLabel": "Look up", "noSpellCheckReplacementsLabel": "No replacements found", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_en_NZ.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_en_NZ.arb index c0780fe62b876..fc2b48b92e57f 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_en_NZ.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_en_NZ.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "lookUpButtonLabel": "Look up", "noSpellCheckReplacementsLabel": "No replacements found", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_en_SG.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_en_SG.arb index c0780fe62b876..fc2b48b92e57f 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_en_SG.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_en_SG.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "lookUpButtonLabel": "Look up", "noSpellCheckReplacementsLabel": "No replacements found", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_en_ZA.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_en_ZA.arb index c0780fe62b876..fc2b48b92e57f 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_en_ZA.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_en_ZA.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "lookUpButtonLabel": "Look up", "noSpellCheckReplacementsLabel": "No replacements found", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es.arb index aab7584291ddd..a2955f8ecad57 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Buscar", "noSpellCheckReplacementsLabel": "No se ha encontrado ninguna sustitución", "menuDismissLabel": "Cerrar menú", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Buscador visual", + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_419.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_419.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_419.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_419.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_AR.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_AR.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_AR.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_AR.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_BO.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_BO.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_BO.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_BO.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_CL.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_CL.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_CL.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_CL.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_CO.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_CO.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_CO.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_CO.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_CR.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_CR.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_CR.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_CR.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_DO.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_DO.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_DO.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_DO.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_EC.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_EC.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_EC.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_EC.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_GT.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_GT.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_GT.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_GT.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_HN.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_HN.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_HN.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_HN.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_MX.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_MX.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_MX.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_MX.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_NI.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_NI.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_NI.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_NI.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_PA.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_PA.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_PA.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_PA.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_PE.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_PE.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_PE.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_PE.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_PR.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_PR.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_PR.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_PR.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_PY.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_PY.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_PY.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_PY.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_SV.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_SV.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_SV.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_SV.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_US.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_US.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_US.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_US.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_UY.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_UY.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_UY.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_UY.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_es_VE.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_es_VE.arb index b716dc2b5bb91..1472ffa3cea31 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_es_VE.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_es_VE.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "lookUpButtonLabel": "Mirar hacia arriba", "noSpellCheckReplacementsLabel": "No se encontraron reemplazos", "menuDismissLabel": "Descartar menú", @@ -23,6 +25,6 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Pegar", - "selectAllButtonLabel": "Seleccionar todos", + "selectAllButtonLabel": "Seleccionar todo", "modalBarrierDismissLabel": "Descartar" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_et.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_et.arb index c4c6c6acdc0b7..625806c64ad7e 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_et.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_et.arb @@ -25,6 +25,6 @@ "noSpellCheckReplacementsLabel": "Asendusi ei leitud", "menuDismissLabel": "Sulge menüü", "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Otsi veebist", + "shareButtonLabel": "Jaga …" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_eu.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_eu.arb index 6d72858ff3d96..271d9f3d56bd2 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_eu.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_eu.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Bilatu", "noSpellCheckReplacementsLabel": "Ez da aurkitu ordezteko hitzik", "menuDismissLabel": "Baztertu menua", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Bilatu", + "searchWebButtonLabel": "Bilatu sarean", + "shareButtonLabel": "Partekatu..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_fa.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_fa.arb index a36c89ba40177..c3650f9f5bf1a 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_fa.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_fa.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "جستجو", "noSpellCheckReplacementsLabel": "جایگزینی پیدا نشد", "menuDismissLabel": "بستن منو", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "جستجو", + "searchWebButtonLabel": "جستجو در وب", + "shareButtonLabel": "هم‌رسانی…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_fi.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_fi.arb index 0c56ce534f27b..51d7b61a2860b 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_fi.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_fi.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Hae", "noSpellCheckReplacementsLabel": "Korvaavia sanoja ei löydy", "menuDismissLabel": "Hylkää valikko", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Hae", + "searchWebButtonLabel": "Hae verkosta", + "shareButtonLabel": "Jaa…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_fil.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_fil.arb index e983d4d1a58c9..23ff05e054152 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_fil.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_fil.arb @@ -25,6 +25,6 @@ "noSpellCheckReplacementsLabel": "Walang Nahanap na Kapalit", "menuDismissLabel": "I-dismiss ang menu", "lookUpButtonLabel": "Tumingin sa Itaas", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Maghanap sa Web", + "shareButtonLabel": "Ibahagi..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_fr.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_fr.arb index 57ae553ba1f46..cc17d479defc6 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_fr.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_fr.arb @@ -18,13 +18,13 @@ "cutButtonLabel": "Couper", "copyButtonLabel": "Copier", "pasteButtonLabel": "Coller", - "selectAllButtonLabel": "Tout sélect.", + "selectAllButtonLabel": "Tout sélectionner", "tabSemanticsLabel": "Onglet $tabIndex sur $tabCount", "modalBarrierDismissLabel": "Ignorer", "searchTextFieldPlaceholderLabel": "Rechercher", "noSpellCheckReplacementsLabel": "Aucun remplacement trouvé", "menuDismissLabel": "Fermer le menu", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Recherche visuelle", + "searchWebButtonLabel": "Rechercher sur le Web", + "shareButtonLabel": "Partager…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_fr_CA.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_fr_CA.arb index f86963fca218a..b3cb2d863f8b4 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_fr_CA.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_fr_CA.arb @@ -1,4 +1,7 @@ { + "lookUpButtonLabel": "Regarder en haut", + "searchWebButtonLabel": "Rechercher sur le Web", + "shareButtonLabel": "Partager…", "noSpellCheckReplacementsLabel": "Aucun remplacement trouvé", "menuDismissLabel": "Ignorer le menu", "searchTextFieldPlaceholderLabel": "Rechercher", diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_gl.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_gl.arb index 2949a2246b0ae..33e06cd368f34 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_gl.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_gl.arb @@ -25,6 +25,6 @@ "noSpellCheckReplacementsLabel": "Non se encontrou ningunha substitución", "menuDismissLabel": "Pechar menú", "lookUpButtonLabel": "Mirar cara arriba", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Buscar na Web", + "shareButtonLabel": "Compartir…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_gsw.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_gsw.arb index 5eeefca1c7857..2b3dc4bc9642c 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_gsw.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_gsw.arb @@ -18,13 +18,13 @@ "cutButtonLabel": "Ausschneiden", "copyButtonLabel": "Kopieren", "pasteButtonLabel": "Einsetzen", - "selectAllButtonLabel": "Alles auswählen", + "selectAllButtonLabel": "Alle auswählen", "tabSemanticsLabel": "Tab $tabIndex von $tabCount", "modalBarrierDismissLabel": "Schließen", "searchTextFieldPlaceholderLabel": "Suche", "noSpellCheckReplacementsLabel": "Keine Ersetzungen gefunden", "menuDismissLabel": "Menü schließen", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Nachschlagen", + "searchWebButtonLabel": "Im Web suchen", + "shareButtonLabel": "Teilen…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_gu.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_gu.arb index 40f2602774898..037fb74786047 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_gu.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_gu.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "શોધો", "noSpellCheckReplacementsLabel": "બદલવા માટે કોઈ શબ્દ મળ્યો નથી", "menuDismissLabel": "મેનૂ છોડી દો", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "શોધો", + "searchWebButtonLabel": "વેબ પર શોધો", + "shareButtonLabel": "શેર કરો…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_he.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_he.arb index b2537b0af3836..b447bf7907b17 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_he.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_he.arb @@ -34,7 +34,7 @@ "searchTextFieldPlaceholderLabel": "חיפוש", "noSpellCheckReplacementsLabel": "לא נמצאו חלופות", "menuDismissLabel": "סגירת התפריט", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "חיפוש", + "searchWebButtonLabel": "חיפוש באינטרנט", + "shareButtonLabel": "שיתוף…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_hi.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_hi.arb index d7262f017c029..3a813d4b216c4 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_hi.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_hi.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "खोजें", "noSpellCheckReplacementsLabel": "सही वर्तनी वाला कोई शब्द नहीं मिला", "menuDismissLabel": "मेन्यू खारिज करें", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "लुक अप बटन", + "searchWebButtonLabel": "वेब पर खोजें", + "shareButtonLabel": "शेयर करें…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_hr.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_hr.arb index 9d68b3e925967..cec88659eca98 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_hr.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_hr.arb @@ -30,6 +30,6 @@ "noSpellCheckReplacementsLabel": "Nema pronađenih zamjena", "menuDismissLabel": "Odbacivanje izbornika", "lookUpButtonLabel": "Pogled prema gore", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Pretraži web", + "shareButtonLabel": "Dijeli..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_hu.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_hu.arb index 1d91e5b830bab..82bc5ed331b5f 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_hu.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_hu.arb @@ -25,6 +25,6 @@ "noSpellCheckReplacementsLabel": "Nem található javítás", "menuDismissLabel": "Menü bezárása", "lookUpButtonLabel": "Felfelé nézés", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Keresés az interneten", + "shareButtonLabel": "Megosztás…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_hy.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_hy.arb index 011211fb5c853..ce0baf3484a18 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_hy.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_hy.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Որոնում", "noSpellCheckReplacementsLabel": "Փոխարինումներ չեն գտնվել", "menuDismissLabel": "Փակել ընտրացանկը", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Փնտրել", + "searchWebButtonLabel": "Որոնել համացանցում", + "shareButtonLabel": "Կիսվել..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_id.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_id.arb index 99c0fec3d64be..a8d03a54f9efe 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_id.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_id.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Telusuri", "noSpellCheckReplacementsLabel": "Penggantian Tidak Ditemukan", "menuDismissLabel": "Tutup menu", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Cari", + "searchWebButtonLabel": "Telusuri di Web", + "shareButtonLabel": "Bagikan..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_is.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_is.arb index f71f0c3f59e92..a9e8537792d10 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_is.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_is.arb @@ -25,6 +25,6 @@ "noSpellCheckReplacementsLabel": "Engir staðgenglar fundust", "menuDismissLabel": "Loka valmynd", "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Leita á vefnum", + "shareButtonLabel": "Deila..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_it.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_it.arb index 15c1b1c810288..47f0782203a30 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_it.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_it.arb @@ -25,6 +25,6 @@ "noSpellCheckReplacementsLabel": "Nessuna sostituzione trovata", "menuDismissLabel": "Ignora menu", "lookUpButtonLabel": "Cerca", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Cerca sul web", + "shareButtonLabel": "Condividi…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_ja.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_ja.arb index 3fbfe7d9e057e..1ec0b7a23a81b 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_ja.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_ja.arb @@ -18,13 +18,13 @@ "cutButtonLabel": "切り取り", "copyButtonLabel": "コピー", "pasteButtonLabel": "貼り付け", - "selectAllButtonLabel": "すべて選択", + "selectAllButtonLabel": "すべてを選択", "tabSemanticsLabel": "タブ: $tabIndex/$tabCount", "modalBarrierDismissLabel": "閉じる", "searchTextFieldPlaceholderLabel": "検索", "noSpellCheckReplacementsLabel": "置き換えるものがありません", "menuDismissLabel": "メニューを閉じる", "lookUpButtonLabel": "調べる", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "ウェブを検索", + "shareButtonLabel": "共有..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_ka.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_ka.arb index 825a5c44560e6..8414b5fdc4946 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_ka.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_ka.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "ძიება", "noSpellCheckReplacementsLabel": "ჩანაცვლება არ მოიძებნა", "menuDismissLabel": "მენიუს უარყოფა", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "აიხედეთ ზემოთ", + "searchWebButtonLabel": "ვებში ძიება", + "shareButtonLabel": "გაზიარება..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_kk.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_kk.arb index 8501fc704dd09..c6f84dec670cf 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_kk.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_kk.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Іздеу", "noSpellCheckReplacementsLabel": "Ауыстыратын ешнәрсе табылмады.", "menuDismissLabel": "Мәзірді жабу", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Іздеу", + "searchWebButtonLabel": "Интернеттен іздеу", + "shareButtonLabel": "Бөлісу…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_km.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_km.arb index 37da3ecc0dc66..48a79775a5da6 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_km.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_km.arb @@ -25,6 +25,6 @@ "noSpellCheckReplacementsLabel": "រកមិនឃើញ​ការជំនួសទេ", "menuDismissLabel": "ច្រានចោល​ម៉ឺនុយ", "lookUpButtonLabel": "រកមើល", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "ស្វែងរក​លើបណ្ដាញ", + "shareButtonLabel": "ចែករំលែក..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_kn.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_kn.arb index ea83d91ff3aed..004e4fc2c113d 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_kn.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_kn.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "\u0cb9\u0cc1\u0ca1\u0cc1\u0c95\u0cbf", "noSpellCheckReplacementsLabel": "\u0caf\u0cbe\u0cb5\u0cc1\u0ca6\u0cc7\u0020\u0cac\u0ca6\u0cb2\u0cbe\u0cb5\u0ca3\u0cc6\u0c97\u0cb3\u0cc1\u0020\u0c95\u0c82\u0ca1\u0cc1\u0cac\u0c82\u0ca6\u0cbf\u0cb2\u0ccd\u0cb2", "menuDismissLabel": "\u0cae\u0cc6\u0ca8\u0cc1\u0cb5\u0ca8\u0ccd\u0ca8\u0cc1\u0020\u0cb5\u0c9c\u0cbe\u0c97\u0cc6\u0cc2\u0cb3\u0cbf\u0cb8\u0cbf", - "lookUpButtonLabel": "\u004c\u006f\u006f\u006b\u0020\u0055\u0070", - "searchWebButtonLabel": "\u0053\u0065\u0061\u0072\u0063\u0068\u0020\u0057\u0065\u0062", - "shareButtonLabel": "\u0053\u0068\u0061\u0072\u0065\u002e\u002e\u002e" + "lookUpButtonLabel": "\u0cae\u0cc7\u0cb2\u0cc6\u0020\u0ca8\u0ccb\u0ca1\u0cbf", + "searchWebButtonLabel": "\u0cb5\u0cc6\u0cac\u0ccd\u200c\u0ca8\u0cb2\u0ccd\u0cb2\u0cbf\u0020\u0cb9\u0cc1\u0ca1\u0cc1\u0c95\u0cbf", + "shareButtonLabel": "\u0cb9\u0c82\u0c9a\u0cbf\u0c95\u0cca\u0cb3\u0ccd\u0cb3\u0cbf\u002e\u002e\u002e" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_ko.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_ko.arb index 44e5c3461877b..d11ab74a6695c 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_ko.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_ko.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "검색", "noSpellCheckReplacementsLabel": "수정사항 없음", "menuDismissLabel": "메뉴 닫기", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "찾기", + "searchWebButtonLabel": "웹 검색", + "shareButtonLabel": "공유..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_ky.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_ky.arb index ed73ad35ea05b..903dd2be8b4a3 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_ky.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_ky.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Издөө", "noSpellCheckReplacementsLabel": "Алмаштыруу үчүн сөз табылган жок", "menuDismissLabel": "Менюну жабуу", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Издөө", + "searchWebButtonLabel": "Интернеттен издөө", + "shareButtonLabel": "Бөлүшүү…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_lo.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_lo.arb index 8e4b6e0785358..6a86167209c0f 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_lo.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_lo.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "ຊອກຫາ", "noSpellCheckReplacementsLabel": "ບໍ່ພົບການແທນທີ່", "menuDismissLabel": "ປິດເມນູ", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "ຊອກຫາຂໍ້ມູນ", + "searchWebButtonLabel": "ຊອກຫາຢູ່ອິນເຕີເນັດ", + "shareButtonLabel": "ແບ່ງປັນ..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_lt.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_lt.arb index b1939982d36e2..aff454c8dec95 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_lt.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_lt.arb @@ -34,7 +34,7 @@ "searchTextFieldPlaceholderLabel": "Paieška", "noSpellCheckReplacementsLabel": "Nerasta jokių pakeitimų", "menuDismissLabel": "Atsisakyti meniu", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Ieškoti", + "searchWebButtonLabel": "Ieškoti žiniatinklyje", + "shareButtonLabel": "Bendrinti..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_lv.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_lv.arb index 9a7943d06c150..8af3414db902e 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_lv.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_lv.arb @@ -29,7 +29,7 @@ "searchTextFieldPlaceholderLabel": "Meklēšana", "noSpellCheckReplacementsLabel": "Netika atrasts neviens vārds aizstāšanai", "menuDismissLabel": "Nerādīt izvēlni", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Meklēt", + "searchWebButtonLabel": "Meklēt tīmeklī", + "shareButtonLabel": "Kopīgot…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_mk.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_mk.arb index ad88d5b9cec1c..d0bbe62160fe2 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_mk.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_mk.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Пребарувајте", "noSpellCheckReplacementsLabel": "Не се најдени заменски зборови", "menuDismissLabel": "Отфрлете го менито", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Погледнете нагоре", + "searchWebButtonLabel": "Пребарајте на интернет", + "shareButtonLabel": "Споделете..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_ml.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_ml.arb index da34cc0fe3922..ffbfa64c22db8 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_ml.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_ml.arb @@ -25,6 +25,6 @@ "noSpellCheckReplacementsLabel": "റീപ്ലേസ്‌മെന്റുകളൊന്നും കണ്ടെത്തിയില്ല", "menuDismissLabel": "മെനു ഡിസ്മിസ് ചെയ്യുക", "lookUpButtonLabel": "മുകളിലേക്ക് നോക്കുക", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "വെബിൽ തിരയുക", + "shareButtonLabel": "പങ്കിടുക..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_mn.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_mn.arb index b8e4f2872babd..1e7c1af1a46fa 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_mn.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_mn.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Хайх", "noSpellCheckReplacementsLabel": "Ямар ч орлуулалт олдсонгүй", "menuDismissLabel": "Цэсийг хаах", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Дээшээ харах", + "searchWebButtonLabel": "Вебээс хайх", + "shareButtonLabel": "Хуваалцах..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_mr.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_mr.arb index fae07c75fbd43..a02f49131ecd5 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_mr.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_mr.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "शोधा", "noSpellCheckReplacementsLabel": "कोणतेही बदल आढळले नाहीत", "menuDismissLabel": "मेनू डिसमिस करा", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "शोध घ्या", + "searchWebButtonLabel": "वेबवर शोधा", + "shareButtonLabel": "शेअर करा..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_ms.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_ms.arb index d38bc94049ea5..4da772d653e8f 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_ms.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_ms.arb @@ -25,6 +25,6 @@ "noSpellCheckReplacementsLabel": "Tiada Penggantian Ditemukan", "menuDismissLabel": "Ketepikan menu", "lookUpButtonLabel": "Lihat ke Atas", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Buat carian pada Web", + "shareButtonLabel": "Kongsi..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_my.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_my.arb index 2f58733fea43b..a67234b7c80fa 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_my.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_my.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "ရှာရန်", "noSpellCheckReplacementsLabel": "အစားထိုးမှုများ မတွေ့ပါ", "menuDismissLabel": "မီနူးကိုပယ်ပါ", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "အပေါ်ကြည့်ရန်", + "searchWebButtonLabel": "ဝဘ်တွင်ရှာရန်", + "shareButtonLabel": "မျှဝေရန်..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_nb.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_nb.arb index 5492d2cbe0e28..5993921bc5934 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_nb.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_nb.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Søk", "noSpellCheckReplacementsLabel": "Fant ingen erstatninger", "menuDismissLabel": "Lukk menyen", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Slå opp", + "searchWebButtonLabel": "Søk på nettet", + "shareButtonLabel": "Del…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_ne.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_ne.arb index 5738d2472ddbd..c7d5499762bf4 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_ne.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_ne.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "खोज्नुहोस्", "noSpellCheckReplacementsLabel": "बदल्नु पर्ने कुनै पनि कुरा भेटिएन", "menuDismissLabel": "मेनु खारेज गर्नुहोस्", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "माथितिर हेर्नुहोस्", + "searchWebButtonLabel": "वेबमा खोज्नुहोस्", + "shareButtonLabel": "सेयर गर्नुहोस्..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_nl.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_nl.arb index d101c83979bc9..d595740ce3eb4 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_nl.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_nl.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Zoeken", "noSpellCheckReplacementsLabel": "Geen vervangingen gevonden", "menuDismissLabel": "Menu sluiten", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Opzoeken", + "searchWebButtonLabel": "Op internet zoeken", + "shareButtonLabel": "Delen..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_no.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_no.arb index 5492d2cbe0e28..5993921bc5934 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_no.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_no.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Søk", "noSpellCheckReplacementsLabel": "Fant ingen erstatninger", "menuDismissLabel": "Lukk menyen", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Slå opp", + "searchWebButtonLabel": "Søk på nettet", + "shareButtonLabel": "Del…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_or.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_or.arb index 72de165a9ecf1..dca2ff3645ec3 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_or.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_or.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "ସନ୍ଧାନ କରନ୍ତୁ", "noSpellCheckReplacementsLabel": "କୌଣସି ରିପ୍ଲେସମେଣ୍ଟ ମିଳିଲା ନାହିଁ", "menuDismissLabel": "ମେନୁ ଖାରଜ କରନ୍ତୁ", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "ଉପରକୁ ଦେଖନ୍ତୁ", + "searchWebButtonLabel": "ୱେବ ସର୍ଚ୍ଚ କରନ୍ତୁ", + "shareButtonLabel": "ସେୟାର୍ କରନ୍ତୁ..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_pa.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_pa.arb index ad72fbfbf4427..1bf80d9daba42 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_pa.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_pa.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "ਖੋਜੋ", "noSpellCheckReplacementsLabel": "ਕੋਈ ਸੁਝਾਅ ਨਹੀਂ ਮਿਲਿਆ", "menuDismissLabel": "ਮੀਨੂ ਖਾਰਜ ਕਰੋ", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "ਖੋਜੋ", + "searchWebButtonLabel": "ਵੈੱਬ 'ਤੇ ਖੋਜੋ", + "shareButtonLabel": "ਸਾਂਝਾ ਕਰੋ..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_pl.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_pl.arb index 36c88c9ebf498..0a94ba81b6b74 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_pl.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_pl.arb @@ -35,6 +35,6 @@ "noSpellCheckReplacementsLabel": "Brak wyników zamieniania", "menuDismissLabel": "Zamknij menu", "lookUpButtonLabel": "Sprawdź", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Szukaj w internecie", + "shareButtonLabel": "Udostępnij…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_pt.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_pt.arb index 29c1cf87062df..4427541cf2ac1 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_pt.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_pt.arb @@ -18,13 +18,13 @@ "cutButtonLabel": "Cortar", "copyButtonLabel": "Copiar", "pasteButtonLabel": "Colar", - "selectAllButtonLabel": "Selecionar Tudo", + "selectAllButtonLabel": "Selecionar tudo", "tabSemanticsLabel": "Guia $tabIndex de $tabCount", "modalBarrierDismissLabel": "Dispensar", "searchTextFieldPlaceholderLabel": "Pesquisar", "noSpellCheckReplacementsLabel": "Nenhuma alternativa encontrada", "menuDismissLabel": "Dispensar menu", "lookUpButtonLabel": "Pesquisar", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Pesquisar na Web", + "shareButtonLabel": "Compartilhar…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_pt_PT.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_pt_PT.arb index 986e169d53cc4..64ec613abc12f 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_pt_PT.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_pt_PT.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Pesquisar na Web", + "shareButtonLabel": "Partilhar…", "lookUpButtonLabel": "Procurar", "noSpellCheckReplacementsLabel": "Não foram encontradas substituições", "menuDismissLabel": "Ignorar menu", diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_ro.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_ro.arb index e78637cf5ee65..f057311ecac99 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_ro.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_ro.arb @@ -23,13 +23,13 @@ "cutButtonLabel": "Decupați", "copyButtonLabel": "Copiați", "pasteButtonLabel": "Inserați", - "selectAllButtonLabel": "Selectați-le pe toate", + "selectAllButtonLabel": "Selectează tot", "tabSemanticsLabel": "Fila $tabIndex din $tabCount", "modalBarrierDismissLabel": "Închideți", "searchTextFieldPlaceholderLabel": "Căutați", "noSpellCheckReplacementsLabel": "Nu s-au găsit înlocuiri", "menuDismissLabel": "Respingeți meniul", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Privire în sus", + "searchWebButtonLabel": "Căutați pe web", + "shareButtonLabel": "Trimiteți…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_ru.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_ru.arb index c0e93bea0954e..6895a097718d9 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_ru.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_ru.arb @@ -34,7 +34,7 @@ "searchTextFieldPlaceholderLabel": "Поиск", "noSpellCheckReplacementsLabel": "Варианты замены не найдены", "menuDismissLabel": "Закрыть меню", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Найти", + "searchWebButtonLabel": "Искать в интернете", + "shareButtonLabel": "Поделиться" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_si.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_si.arb index 35a98c19b7120..d27c802353cde 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_si.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_si.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "සෙවීම", "noSpellCheckReplacementsLabel": "ප්‍රතිස්ථාපන හමු නොවිණි", "menuDismissLabel": "මෙනුව අස් කරන්න", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "උඩ බලන්න", + "searchWebButtonLabel": "වෙබය සොයන්න", + "shareButtonLabel": "බෙදා ගන්න..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_sk.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_sk.arb index 6bce1b40316a1..ab26cadb45698 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_sk.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_sk.arb @@ -28,13 +28,13 @@ "cutButtonLabel": "Vystrihnúť", "copyButtonLabel": "Kopírovať", "pasteButtonLabel": "Prilepiť", - "selectAllButtonLabel": "Vybrať všetko", + "selectAllButtonLabel": "Označiť všetko", "tabSemanticsLabel": "Karta $tabIndex z $tabCount", "modalBarrierDismissLabel": "Odmietnuť", "searchTextFieldPlaceholderLabel": "Hľadať", "noSpellCheckReplacementsLabel": "Nenašli sa žiadne náhrady", "menuDismissLabel": "Zavrieť ponuku", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Pohľad nahor", + "searchWebButtonLabel": "Hľadať na webe", + "shareButtonLabel": "Zdieľať…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_sl.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_sl.arb index 466533c382c2c..113e9bfa3d12a 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_sl.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_sl.arb @@ -34,7 +34,7 @@ "searchTextFieldPlaceholderLabel": "Iskanje", "noSpellCheckReplacementsLabel": "Ni zamenjav", "menuDismissLabel": "Opusti meni", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Pogled gor", + "searchWebButtonLabel": "Iskanje v spletu", + "shareButtonLabel": "Deli …" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_sq.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_sq.arb index f7f2ba5de95ce..4a0c7fe54554b 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_sq.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_sq.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Kërko", "noSpellCheckReplacementsLabel": "Nuk u gjetën zëvendësime", "menuDismissLabel": "Hiqe menynë", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Kërko", + "searchWebButtonLabel": "Kërko në ueb", + "shareButtonLabel": "Ndaj..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_sr.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_sr.arb index da22e63e74863..b2b81e23e6811 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_sr.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_sr.arb @@ -29,7 +29,7 @@ "searchTextFieldPlaceholderLabel": "Претражите", "noSpellCheckReplacementsLabel": "Нису пронађене замене", "menuDismissLabel": "Одбаците мени", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Поглед нагоре", + "searchWebButtonLabel": "Претражи веб", + "shareButtonLabel": "Дели…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_sr_Latn.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_sr_Latn.arb index 02c2db4f38591..0338175735f44 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_sr_Latn.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_sr_Latn.arb @@ -1,4 +1,7 @@ { + "lookUpButtonLabel": "Pogled nagore", + "searchWebButtonLabel": "Pretraži veb", + "shareButtonLabel": "Deli…", "noSpellCheckReplacementsLabel": "Nisu pronađene zamene", "menuDismissLabel": "Odbacite meni", "searchTextFieldPlaceholderLabel": "Pretražite", diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_sv.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_sv.arb index 3fceee58ba699..83ae81a760e17 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_sv.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_sv.arb @@ -18,13 +18,13 @@ "cutButtonLabel": "Klipp ut", "copyButtonLabel": "Kopiera", "pasteButtonLabel": "Klistra in", - "selectAllButtonLabel": "Markera alla", + "selectAllButtonLabel": "Markera allt", "tabSemanticsLabel": "Flik $tabIndex av $tabCount", "modalBarrierDismissLabel": "Stäng", "searchTextFieldPlaceholderLabel": "Sök", "noSpellCheckReplacementsLabel": "Inga ersättningar hittades", "menuDismissLabel": "Stäng menyn", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Titta upp", + "searchWebButtonLabel": "Sök på webben", + "shareButtonLabel": "Dela …" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_sw.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_sw.arb index 3836a6c61d859..52cd75fc76ecf 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_sw.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_sw.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Tafuta", "noSpellCheckReplacementsLabel": "Hakuna Neno Mbadala Lilopatikana", "menuDismissLabel": "Ondoa menyu", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Tafuta", + "searchWebButtonLabel": "Tafuta kwenye Wavuti", + "shareButtonLabel": "Shiriki..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_ta.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_ta.arb index fb43d1bc64700..51fa93289e36d 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_ta.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_ta.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "தேடுக", "noSpellCheckReplacementsLabel": "மாற்று வார்த்தைகள் கிடைக்கவில்லை", "menuDismissLabel": "மெனுவை மூடும்", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "தேடு", + "searchWebButtonLabel": "இணையத்தில் தேடு", + "shareButtonLabel": "பகிர்..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_te.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_te.arb index 0e53a7e958255..4ade0b2639f26 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_te.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_te.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "సెర్చ్ చేయి", "noSpellCheckReplacementsLabel": "రీప్లేస్‌మెంట్‌లు ఏవీ కనుగొనబడలేదు", "menuDismissLabel": "మెనూను తీసివేయండి", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "వెతకండి", + "searchWebButtonLabel": "వెబ్‌లో సెర్చ్ చేయండి", + "shareButtonLabel": "షేర్ చేయండి..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_th.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_th.arb index c6699874372f3..b1767550e0b58 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_th.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_th.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "ค้นหา", "noSpellCheckReplacementsLabel": "ไม่พบรายการแทนที่", "menuDismissLabel": "ปิดเมนู", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "ค้นหา", + "searchWebButtonLabel": "ค้นหาบนอินเทอร์เน็ต", + "shareButtonLabel": "แชร์..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_tl.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_tl.arb index e983d4d1a58c9..23ff05e054152 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_tl.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_tl.arb @@ -25,6 +25,6 @@ "noSpellCheckReplacementsLabel": "Walang Nahanap na Kapalit", "menuDismissLabel": "I-dismiss ang menu", "lookUpButtonLabel": "Tumingin sa Itaas", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Maghanap sa Web", + "shareButtonLabel": "Ibahagi..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_tr.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_tr.arb index 59bfa3eccf53e..e51abc82ecc96 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_tr.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_tr.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Ara", "noSpellCheckReplacementsLabel": "Yerine Kelime Bulunamadı", "menuDismissLabel": "Menüyü kapat", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Ara", + "searchWebButtonLabel": "Web'de Ara", + "shareButtonLabel": "Paylaş..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_uk.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_uk.arb index 6f50ab997fb9d..6aae12e7cc237 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_uk.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_uk.arb @@ -34,7 +34,7 @@ "searchTextFieldPlaceholderLabel": "Шукайте", "noSpellCheckReplacementsLabel": "Замін не знайдено", "menuDismissLabel": "Закрити меню", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Шукати", + "searchWebButtonLabel": "Пошук в Інтернеті", + "shareButtonLabel": "Поділитися…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_ur.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_ur.arb index ca0282cc6d285..7cf4e71d7fda9 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_ur.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_ur.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "تلاش کریں", "noSpellCheckReplacementsLabel": "کوئی تبدیلیاں نہیں ملیں", "menuDismissLabel": "مینو برخاست کریں", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "تفصیل دیکھیں", + "searchWebButtonLabel": "ویب تلاش کریں", + "shareButtonLabel": "اشتراک کریں..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_uz.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_uz.arb index 86fd969dab4f8..9f72d348fbbc8 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_uz.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_uz.arb @@ -25,6 +25,6 @@ "noSpellCheckReplacementsLabel": "Almashtirish uchun soʻz topilmadi", "menuDismissLabel": "Menyuni yopish", "lookUpButtonLabel": "Tepaga qarang", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Internetdan qidirish", + "shareButtonLabel": "Ulashish…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_vi.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_vi.arb index 4b8277007bfd0..b3bd42ded6584 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_vi.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_vi.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Tìm kiếm", "noSpellCheckReplacementsLabel": "Không tìm thấy phương án thay thế", "menuDismissLabel": "Đóng trình đơn", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Tra cứu", + "searchWebButtonLabel": "Tìm kiếm trên web", + "shareButtonLabel": "Chia sẻ..." } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_zh.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_zh.arb index 98f18f4ab1237..eb126265fd5f9 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_zh.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_zh.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "搜索", "noSpellCheckReplacementsLabel": "找不到替换文字", "menuDismissLabel": "关闭菜单", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "向上看", + "searchWebButtonLabel": "在网络上搜索", + "shareButtonLabel": "分享…" } diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_zh_HK.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_zh_HK.arb index 5cac05b161314..d580720057600 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_zh_HK.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_zh_HK.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "搜尋網頁", + "shareButtonLabel": "分享…", "lookUpButtonLabel": "查詢", "noSpellCheckReplacementsLabel": "找不到替換字詞", "menuDismissLabel": "閂選單", diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_zh_TW.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_zh_TW.arb index 2c1190da6c0fc..3b5532c9df213 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_zh_TW.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_zh_TW.arb @@ -1,4 +1,7 @@ { + "lookUpButtonLabel": "查詢", + "searchWebButtonLabel": "在網路上搜尋", + "shareButtonLabel": "分享…", "noSpellCheckReplacementsLabel": "找不到替代文字", "menuDismissLabel": "關閉選單", "searchTextFieldPlaceholderLabel": "搜尋", diff --git a/packages/flutter_localizations/lib/src/l10n/cupertino_zu.arb b/packages/flutter_localizations/lib/src/l10n/cupertino_zu.arb index 6e37c0fa0e0a8..900145fb96b15 100644 --- a/packages/flutter_localizations/lib/src/l10n/cupertino_zu.arb +++ b/packages/flutter_localizations/lib/src/l10n/cupertino_zu.arb @@ -24,7 +24,7 @@ "searchTextFieldPlaceholderLabel": "Sesha", "noSpellCheckReplacementsLabel": "Akukho Okuzofakwa Esikhundleni Okutholakele", "menuDismissLabel": "Chitha imenyu", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Bheka Phezulu", + "searchWebButtonLabel": "Sesha Iwebhu", + "shareButtonLabel": "Yabelana..." } diff --git a/packages/flutter_localizations/lib/src/l10n/generated_cupertino_localizations.dart b/packages/flutter_localizations/lib/src/l10n/generated_cupertino_localizations.dart index 4b584dcc61eb5..21797c40ecb80 100644 --- a/packages/flutter_localizations/lib/src/l10n/generated_cupertino_localizations.dart +++ b/packages/flutter_localizations/lib/src/l10n/generated_cupertino_localizations.dart @@ -92,7 +92,7 @@ class CupertinoLocalizationAf extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Kyk op'; @override String get menuDismissLabel => 'Maak kieslys toe'; @@ -113,13 +113,13 @@ class CupertinoLocalizationAf extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Soek'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Deursoek web'; @override String get selectAllButtonLabel => 'Kies alles'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Deel …'; @override String get tabSemanticsLabelRaw => r'Oortjie $tabIndex van $tabCount'; @@ -254,7 +254,7 @@ class CupertinoLocalizationAm extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'ይመልከቱ'; @override String get menuDismissLabel => 'ምናሌን አሰናብት'; @@ -275,13 +275,13 @@ class CupertinoLocalizationAm extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'ፍለጋ'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ድርን ፈልግ'; @override String get selectAllButtonLabel => 'ሁሉንም ምረጥ'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'አጋራ...'; @override String get tabSemanticsLabelRaw => r'ትር $tabIndex ከ$tabCount'; @@ -416,7 +416,7 @@ class CupertinoLocalizationAr extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => r'$minute دقيقة​'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'النظر إلى أعلى'; @override String get menuDismissLabel => 'إغلاق القائمة'; @@ -437,13 +437,13 @@ class CupertinoLocalizationAr extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'بحث'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'البحث على الويب'; @override String get selectAllButtonLabel => 'اختيار الكل'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'مشاركة…'; @override String get tabSemanticsLabelRaw => r'علامة التبويب $tabIndex من $tabCount'; @@ -578,7 +578,7 @@ class CupertinoLocalizationAs extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'ওপৰলৈ চাওক'; @override String get menuDismissLabel => 'অগ্ৰাহ্য কৰাৰ মেনু'; @@ -599,13 +599,13 @@ class CupertinoLocalizationAs extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'সন্ধান কৰক'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ৱেবত সন্ধান কৰক'; @override String get selectAllButtonLabel => 'সকলো বাছনি কৰক'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'শ্বেয়াৰ কৰক…'; @override String get tabSemanticsLabelRaw => r'$tabCount টা টেবৰ $tabIndex নম্বৰটো'; @@ -740,7 +740,7 @@ class CupertinoLocalizationAz extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Axtarın'; @override String get menuDismissLabel => 'Menyunu qapadın'; @@ -761,13 +761,13 @@ class CupertinoLocalizationAz extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Axtarın'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Vebdə axtarın'; @override String get selectAllButtonLabel => 'Hamısını seçin'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Paylaşın...'; @override String get tabSemanticsLabelRaw => r'Tab $tabIndex/$tabCount'; @@ -902,7 +902,7 @@ class CupertinoLocalizationBe extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Знайсці'; @override String get menuDismissLabel => 'Закрыць меню'; @@ -923,13 +923,13 @@ class CupertinoLocalizationBe extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Пошук'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Пошук у сетцы'; @override String get selectAllButtonLabel => 'Выбраць усе'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Абагуліць...'; @override String get tabSemanticsLabelRaw => r'Укладка $tabIndex з $tabCount'; @@ -1085,13 +1085,13 @@ class CupertinoLocalizationBg extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Търсене'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Търсене в мрежата'; @override String get selectAllButtonLabel => 'Избиране на всички'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Споделяне...'; @override String get tabSemanticsLabelRaw => r'Раздел $tabIndex от $tabCount'; @@ -1226,7 +1226,7 @@ class CupertinoLocalizationBn extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'লুক-আপ'; @override String get menuDismissLabel => 'বাতিল করার মেনু'; @@ -1247,13 +1247,13 @@ class CupertinoLocalizationBn extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'সার্চ করুন'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ওয়েবে সার্চ করুন'; @override String get selectAllButtonLabel => 'সব বেছে নিন'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'শেয়ার করুন...'; @override String get tabSemanticsLabelRaw => r'$tabCount-এর মধ্যে $tabIndex নম্বর ট্যাব'; @@ -1388,7 +1388,7 @@ class CupertinoLocalizationBs extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Pogled prema gore'; + String get lookUpButtonLabel => 'Pogled nagore'; @override String get menuDismissLabel => 'Odbacivanje menija'; @@ -1409,13 +1409,13 @@ class CupertinoLocalizationBs extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Pretraživanje'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Pretraži Web'; @override String get selectAllButtonLabel => 'Odaberi sve'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Dijeli...'; @override String get tabSemanticsLabelRaw => r'Kartica $tabIndex od $tabCount'; @@ -1550,7 +1550,7 @@ class CupertinoLocalizationCa extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Mira amunt'; @override String get menuDismissLabel => 'Ignora el menú'; @@ -1571,13 +1571,13 @@ class CupertinoLocalizationCa extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Cerca'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Cerca al web'; @override - String get selectAllButtonLabel => 'Selecciona-ho tot'; + String get selectAllButtonLabel => 'Seleccionar-ho tot'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Comparteix...'; @override String get tabSemanticsLabelRaw => r'Pestanya $tabIndex de $tabCount'; @@ -1712,7 +1712,7 @@ class CupertinoLocalizationCs extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Vyhledat'; @override String get menuDismissLabel => 'Zavřít nabídku'; @@ -1733,13 +1733,13 @@ class CupertinoLocalizationCs extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Hledat'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Vyhledávat na webu'; @override String get selectAllButtonLabel => 'Vybrat vše'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Sdílet…'; @override String get tabSemanticsLabelRaw => r'Karta $tabIndex z $tabCount'; @@ -1874,7 +1874,7 @@ class CupertinoLocalizationCy extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => r'$minute munud'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Chwilio'; @override String get menuDismissLabel => "Diystyru'r ddewislen"; @@ -1895,13 +1895,13 @@ class CupertinoLocalizationCy extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Chwilio'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => "Chwilio'r We"; @override String get selectAllButtonLabel => 'Dewis y Cyfan'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Rhannu...'; @override String get tabSemanticsLabelRaw => r'Tab $tabIndex o $tabCount'; @@ -2036,7 +2036,7 @@ class CupertinoLocalizationDa extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Slå op'; @override String get menuDismissLabel => 'Luk menu'; @@ -2057,13 +2057,13 @@ class CupertinoLocalizationDa extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Søg'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Søg på nettet'; @override - String get selectAllButtonLabel => 'Vælg alle'; + String get selectAllButtonLabel => 'Vælg alt'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Del…'; @override String get tabSemanticsLabelRaw => r'Fane $tabIndex af $tabCount'; @@ -2198,7 +2198,7 @@ class CupertinoLocalizationDe extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Nachschlagen'; @override String get menuDismissLabel => 'Menü schließen'; @@ -2219,13 +2219,13 @@ class CupertinoLocalizationDe extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Suche'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Im Web suchen'; @override - String get selectAllButtonLabel => 'Alles auswählen'; + String get selectAllButtonLabel => 'Alle auswählen'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Teilen…'; @override String get tabSemanticsLabelRaw => r'Tab $tabIndex von $tabCount'; @@ -2305,6 +2305,9 @@ class CupertinoLocalizationDeCh extends CupertinoLocalizationDe { required super.decimalFormat, }); + @override + String get selectAllButtonLabel => 'Alles auswählen'; + @override String get modalBarrierDismissLabel => 'Schliessen'; } @@ -2402,13 +2405,13 @@ class CupertinoLocalizationEl extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Αναζήτηση'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Αναζήτηση στον ιστό'; @override String get selectAllButtonLabel => 'Επιλογή όλων'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Κοινοποίηση…'; @override String get tabSemanticsLabelRaw => r'Καρτέλα $tabIndex από $tabCount'; @@ -2939,7 +2942,7 @@ class CupertinoLocalizationEs extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Buscador visual'; @override String get menuDismissLabel => 'Cerrar menú'; @@ -2960,13 +2963,13 @@ class CupertinoLocalizationEs extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Buscar'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Buscar en la Web'; @override String get selectAllButtonLabel => 'Seleccionar todo'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Compartir...'; @override String get tabSemanticsLabelRaw => r'Pestaña $tabIndex de $tabCount'; @@ -3046,6 +3049,9 @@ class CupertinoLocalizationEs419 extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3067,9 +3073,6 @@ class CupertinoLocalizationEs419 extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3091,6 +3094,9 @@ class CupertinoLocalizationEsAr extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3112,9 +3118,6 @@ class CupertinoLocalizationEsAr extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3136,6 +3139,9 @@ class CupertinoLocalizationEsBo extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3157,9 +3163,6 @@ class CupertinoLocalizationEsBo extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3181,6 +3184,9 @@ class CupertinoLocalizationEsCl extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3202,9 +3208,6 @@ class CupertinoLocalizationEsCl extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3226,6 +3229,9 @@ class CupertinoLocalizationEsCo extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3247,9 +3253,6 @@ class CupertinoLocalizationEsCo extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3271,6 +3274,9 @@ class CupertinoLocalizationEsCr extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3292,9 +3298,6 @@ class CupertinoLocalizationEsCr extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3316,6 +3319,9 @@ class CupertinoLocalizationEsDo extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3337,9 +3343,6 @@ class CupertinoLocalizationEsDo extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3361,6 +3364,9 @@ class CupertinoLocalizationEsEc extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3382,9 +3388,6 @@ class CupertinoLocalizationEsEc extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3406,6 +3409,9 @@ class CupertinoLocalizationEsGt extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3427,9 +3433,6 @@ class CupertinoLocalizationEsGt extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3451,6 +3454,9 @@ class CupertinoLocalizationEsHn extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3472,9 +3478,6 @@ class CupertinoLocalizationEsHn extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3496,6 +3499,9 @@ class CupertinoLocalizationEsMx extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3517,9 +3523,6 @@ class CupertinoLocalizationEsMx extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3541,6 +3544,9 @@ class CupertinoLocalizationEsNi extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3562,9 +3568,6 @@ class CupertinoLocalizationEsNi extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3586,6 +3589,9 @@ class CupertinoLocalizationEsPa extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3607,9 +3613,6 @@ class CupertinoLocalizationEsPa extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3631,6 +3634,9 @@ class CupertinoLocalizationEsPe extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3652,9 +3658,6 @@ class CupertinoLocalizationEsPe extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3676,6 +3679,9 @@ class CupertinoLocalizationEsPr extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3697,9 +3703,6 @@ class CupertinoLocalizationEsPr extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3721,6 +3724,9 @@ class CupertinoLocalizationEsPy extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3742,9 +3748,6 @@ class CupertinoLocalizationEsPy extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3766,6 +3769,9 @@ class CupertinoLocalizationEsSv extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3787,9 +3793,6 @@ class CupertinoLocalizationEsSv extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3811,6 +3814,9 @@ class CupertinoLocalizationEsUs extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3832,9 +3838,6 @@ class CupertinoLocalizationEsUs extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3856,6 +3859,9 @@ class CupertinoLocalizationEsUy extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3877,9 +3883,6 @@ class CupertinoLocalizationEsUy extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -3901,6 +3904,9 @@ class CupertinoLocalizationEsVe extends CupertinoLocalizationEs { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get lookUpButtonLabel => 'Mirar hacia arriba'; @@ -3922,9 +3928,6 @@ class CupertinoLocalizationEsVe extends CupertinoLocalizationEs { @override String get postMeridiemAbbreviation => 'p.m.'; - @override - String get selectAllButtonLabel => 'Seleccionar todos'; - @override String get modalBarrierDismissLabel => 'Descartar'; } @@ -4022,13 +4025,13 @@ class CupertinoLocalizationEt extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Otsige'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Otsi veebist'; @override String get selectAllButtonLabel => 'Vali kõik'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Jaga …'; @override String get tabSemanticsLabelRaw => r'$tabIndex. vaheleht $tabCount-st'; @@ -4163,7 +4166,7 @@ class CupertinoLocalizationEu extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Bilatu'; @override String get menuDismissLabel => 'Baztertu menua'; @@ -4184,13 +4187,13 @@ class CupertinoLocalizationEu extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Bilatu'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Bilatu sarean'; @override String get selectAllButtonLabel => 'Hautatu dena'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Partekatu...'; @override String get tabSemanticsLabelRaw => r'$tabIndex/$tabCount fitxa'; @@ -4325,7 +4328,7 @@ class CupertinoLocalizationFa extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'جستجو'; @override String get menuDismissLabel => 'بستن منو'; @@ -4346,13 +4349,13 @@ class CupertinoLocalizationFa extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'جستجو'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'جستجو در وب'; @override String get selectAllButtonLabel => 'انتخاب همه'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'هم‌رسانی…'; @override String get tabSemanticsLabelRaw => r'برگه $tabIndex از $tabCount'; @@ -4487,7 +4490,7 @@ class CupertinoLocalizationFi extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Hae'; @override String get menuDismissLabel => 'Hylkää valikko'; @@ -4508,13 +4511,13 @@ class CupertinoLocalizationFi extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Hae'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Hae verkosta'; @override String get selectAllButtonLabel => 'Valitse kaikki'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Jaa…'; @override String get tabSemanticsLabelRaw => r'Välilehti $tabIndex kautta $tabCount'; @@ -4670,13 +4673,13 @@ class CupertinoLocalizationFil extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Hanapin'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Maghanap sa Web'; @override String get selectAllButtonLabel => 'Piliin Lahat'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Ibahagi...'; @override String get tabSemanticsLabelRaw => r'Tab $tabIndex ng $tabCount'; @@ -4811,7 +4814,7 @@ class CupertinoLocalizationFr extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Recherche visuelle'; @override String get menuDismissLabel => 'Fermer le menu'; @@ -4832,13 +4835,13 @@ class CupertinoLocalizationFr extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Rechercher'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Rechercher sur le Web'; @override - String get selectAllButtonLabel => 'Tout sélect.'; + String get selectAllButtonLabel => 'Tout sélectionner'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Partager…'; @override String get tabSemanticsLabelRaw => r'Onglet $tabIndex sur $tabCount'; @@ -4918,6 +4921,9 @@ class CupertinoLocalizationFrCa extends CupertinoLocalizationFr { required super.decimalFormat, }); + @override + String get lookUpButtonLabel => 'Regarder en haut'; + @override String get menuDismissLabel => 'Ignorer le menu'; @@ -4941,9 +4947,6 @@ class CupertinoLocalizationFrCa extends CupertinoLocalizationFr { @override String get timerPickerMinuteLabelOther => 'min'; - - @override - String get selectAllButtonLabel => 'Tout sélectionner'; } /// The translations for Galician (`gl`). @@ -5039,13 +5042,13 @@ class CupertinoLocalizationGl extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Fai unha busca'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Buscar na Web'; @override String get selectAllButtonLabel => 'Seleccionar todo'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Compartir…'; @override String get tabSemanticsLabelRaw => r'Pestana $tabIndex de $tabCount'; @@ -5180,7 +5183,7 @@ class CupertinoLocalizationGsw extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Nachschlagen'; @override String get menuDismissLabel => 'Menü schließen'; @@ -5201,13 +5204,13 @@ class CupertinoLocalizationGsw extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Suche'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Im Web suchen'; @override - String get selectAllButtonLabel => 'Alles auswählen'; + String get selectAllButtonLabel => 'Alle auswählen'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Teilen…'; @override String get tabSemanticsLabelRaw => r'Tab $tabIndex von $tabCount'; @@ -5342,7 +5345,7 @@ class CupertinoLocalizationGu extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'શોધો'; @override String get menuDismissLabel => 'મેનૂ છોડી દો'; @@ -5363,13 +5366,13 @@ class CupertinoLocalizationGu extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'શોધો'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'વેબ પર શોધો'; @override String get selectAllButtonLabel => 'બધા પસંદ કરો'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'શેર કરો…'; @override String get tabSemanticsLabelRaw => r'$tabCountમાંથી $tabIndex ટૅબ'; @@ -5504,7 +5507,7 @@ class CupertinoLocalizationHe extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'חיפוש'; @override String get menuDismissLabel => 'סגירת התפריט'; @@ -5525,13 +5528,13 @@ class CupertinoLocalizationHe extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'חיפוש'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'חיפוש באינטרנט'; @override String get selectAllButtonLabel => 'בחירת הכול'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'שיתוף…'; @override String get tabSemanticsLabelRaw => r'כרטיסייה $tabIndex מתוך $tabCount'; @@ -5666,7 +5669,7 @@ class CupertinoLocalizationHi extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'लुक अप बटन'; @override String get menuDismissLabel => 'मेन्यू खारिज करें'; @@ -5687,13 +5690,13 @@ class CupertinoLocalizationHi extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'खोजें'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'वेब पर खोजें'; @override String get selectAllButtonLabel => 'सभी चुनें'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'शेयर करें…'; @override String get tabSemanticsLabelRaw => r'$tabCount का टैब $tabIndex'; @@ -5849,13 +5852,13 @@ class CupertinoLocalizationHr extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Pretraživanje'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Pretraži web'; @override String get selectAllButtonLabel => 'Odaberi sve'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Dijeli...'; @override String get tabSemanticsLabelRaw => r'Kartica $tabIndex od $tabCount'; @@ -6011,13 +6014,13 @@ class CupertinoLocalizationHu extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Keresés'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Keresés az interneten'; @override String get selectAllButtonLabel => 'Összes kijelölése'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Megosztás…'; @override String get tabSemanticsLabelRaw => r'$tabCount/$tabIndex. lap'; @@ -6152,7 +6155,7 @@ class CupertinoLocalizationHy extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Փնտրել'; @override String get menuDismissLabel => 'Փակել ընտրացանկը'; @@ -6173,13 +6176,13 @@ class CupertinoLocalizationHy extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Որոնում'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Որոնել համացանցում'; @override String get selectAllButtonLabel => 'Նշել բոլորը'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Կիսվել...'; @override String get tabSemanticsLabelRaw => r'Ներդիր $tabIndex՝ $tabCount-ից'; @@ -6314,7 +6317,7 @@ class CupertinoLocalizationId extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Cari'; @override String get menuDismissLabel => 'Tutup menu'; @@ -6335,13 +6338,13 @@ class CupertinoLocalizationId extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Telusuri'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Telusuri di Web'; @override String get selectAllButtonLabel => 'Pilih Semua'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Bagikan...'; @override String get tabSemanticsLabelRaw => r'Tab $tabIndex dari $tabCount'; @@ -6497,13 +6500,13 @@ class CupertinoLocalizationIs extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Leit'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Leita á vefnum'; @override String get selectAllButtonLabel => 'Velja allt'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Deila...'; @override String get tabSemanticsLabelRaw => r'Flipi $tabIndex af $tabCount'; @@ -6659,13 +6662,13 @@ class CupertinoLocalizationIt extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Cerca'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Cerca sul web'; @override String get selectAllButtonLabel => 'Seleziona tutto'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Condividi…'; @override String get tabSemanticsLabelRaw => r'Scheda $tabIndex di $tabCount'; @@ -6821,13 +6824,13 @@ class CupertinoLocalizationJa extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => '検索'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ウェブを検索'; @override - String get selectAllButtonLabel => 'すべて選択'; + String get selectAllButtonLabel => 'すべてを選択'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => '共有...'; @override String get tabSemanticsLabelRaw => r'タブ: $tabIndex/$tabCount'; @@ -6962,7 +6965,7 @@ class CupertinoLocalizationKa extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'აიხედეთ ზემოთ'; @override String get menuDismissLabel => 'მენიუს უარყოფა'; @@ -6983,13 +6986,13 @@ class CupertinoLocalizationKa extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'ძიება'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ვებში ძიება'; @override String get selectAllButtonLabel => 'ყველას არჩევა'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'გაზიარება...'; @override String get tabSemanticsLabelRaw => r'ჩანართი $tabIndex / $tabCount-დან'; @@ -7124,7 +7127,7 @@ class CupertinoLocalizationKk extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Іздеу'; @override String get menuDismissLabel => 'Мәзірді жабу'; @@ -7145,13 +7148,13 @@ class CupertinoLocalizationKk extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Іздеу'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Интернеттен іздеу'; @override String get selectAllButtonLabel => 'Барлығын таңдау'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Бөлісу…'; @override String get tabSemanticsLabelRaw => r'Қойынды: $tabIndex/$tabCount'; @@ -7307,13 +7310,13 @@ class CupertinoLocalizationKm extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'ស្វែងរក'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ស្វែងរក​លើបណ្ដាញ'; @override String get selectAllButtonLabel => 'ជ្រើសរើស​ទាំងអស់'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'ចែករំលែក...'; @override String get tabSemanticsLabelRaw => r'ផ្ទាំងទី $tabIndex នៃ $tabCount'; @@ -7448,7 +7451,7 @@ class CupertinoLocalizationKn extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => '\u{cae}\u{cc7}\u{cb2}\u{cc6}\u{20}\u{ca8}\u{ccb}\u{ca1}\u{cbf}'; @override String get menuDismissLabel => '\u{cae}\u{cc6}\u{ca8}\u{cc1}\u{cb5}\u{ca8}\u{ccd}\u{ca8}\u{cc1}\u{20}\u{cb5}\u{c9c}\u{cbe}\u{c97}\u{cc6}\u{cc2}\u{cb3}\u{cbf}\u{cb8}\u{cbf}'; @@ -7469,13 +7472,13 @@ class CupertinoLocalizationKn extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => '\u{cb9}\u{cc1}\u{ca1}\u{cc1}\u{c95}\u{cbf}'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => '\u{cb5}\u{cc6}\u{cac}\u{ccd}\u{200c}\u{ca8}\u{cb2}\u{ccd}\u{cb2}\u{cbf}\u{20}\u{cb9}\u{cc1}\u{ca1}\u{cc1}\u{c95}\u{cbf}'; @override String get selectAllButtonLabel => '\u{c8e}\u{cb2}\u{ccd}\u{cb2}\u{cb5}\u{ca8}\u{ccd}\u{ca8}\u{cc2}\u{20}\u{c86}\u{caf}\u{ccd}\u{c95}\u{cc6}\u{cae}\u{cbe}\u{ca1}\u{cbf}'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => '\u{cb9}\u{c82}\u{c9a}\u{cbf}\u{c95}\u{cca}\u{cb3}\u{ccd}\u{cb3}\u{cbf}\u{2e}\u{2e}\u{2e}'; @override String get tabSemanticsLabelRaw => '\u{24}\u{74}\u{61}\u{62}\u{43}\u{6f}\u{75}\u{6e}\u{74}\u{20}\u{cb0}\u{cb2}\u{ccd}\u{cb2}\u{cbf}\u{ca8}\u{20}\u{24}\u{74}\u{61}\u{62}\u{49}\u{6e}\u{64}\u{65}\u{78}\u{20}\u{c9f}\u{ccd}\u{caf}\u{cbe}\u{cac}\u{ccd}'; @@ -7610,7 +7613,7 @@ class CupertinoLocalizationKo extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => '찾기'; @override String get menuDismissLabel => '메뉴 닫기'; @@ -7631,13 +7634,13 @@ class CupertinoLocalizationKo extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => '검색'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => '웹 검색'; @override String get selectAllButtonLabel => '전체 선택'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => '공유...'; @override String get tabSemanticsLabelRaw => r'탭 $tabCount개 중 $tabIndex번째'; @@ -7772,7 +7775,7 @@ class CupertinoLocalizationKy extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Издөө'; @override String get menuDismissLabel => 'Менюну жабуу'; @@ -7793,13 +7796,13 @@ class CupertinoLocalizationKy extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Издөө'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Интернеттен издөө'; @override String get selectAllButtonLabel => 'Баарын тандоо'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Бөлүшүү…'; @override String get tabSemanticsLabelRaw => r'$tabCount ичинен $tabIndex-өтмөк'; @@ -7934,7 +7937,7 @@ class CupertinoLocalizationLo extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'ຊອກຫາຂໍ້ມູນ'; @override String get menuDismissLabel => 'ປິດເມນູ'; @@ -7955,13 +7958,13 @@ class CupertinoLocalizationLo extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'ຊອກຫາ'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ຊອກຫາຢູ່ອິນເຕີເນັດ'; @override String get selectAllButtonLabel => 'ເລືອກທັງໝົດ'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'ແບ່ງປັນ...'; @override String get tabSemanticsLabelRaw => r'ແຖບທີ $tabIndex ຈາກທັງໝົດ $tabCount'; @@ -8096,7 +8099,7 @@ class CupertinoLocalizationLt extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Ieškoti'; @override String get menuDismissLabel => 'Atsisakyti meniu'; @@ -8117,13 +8120,13 @@ class CupertinoLocalizationLt extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Paieška'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Ieškoti žiniatinklyje'; @override String get selectAllButtonLabel => 'Pasirinkti viską'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Bendrinti...'; @override String get tabSemanticsLabelRaw => r'$tabIndex skirtukas iš $tabCount'; @@ -8258,7 +8261,7 @@ class CupertinoLocalizationLv extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => r'$minute minūtes'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Meklēt'; @override String get menuDismissLabel => 'Nerādīt izvēlni'; @@ -8279,13 +8282,13 @@ class CupertinoLocalizationLv extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Meklēšana'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Meklēt tīmeklī'; @override String get selectAllButtonLabel => 'Atlasīt visu'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Kopīgot…'; @override String get tabSemanticsLabelRaw => r'$tabIndex. cilne no $tabCount'; @@ -8420,7 +8423,7 @@ class CupertinoLocalizationMk extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Погледнете нагоре'; @override String get menuDismissLabel => 'Отфрлете го менито'; @@ -8441,13 +8444,13 @@ class CupertinoLocalizationMk extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Пребарувајте'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Пребарајте на интернет'; @override String get selectAllButtonLabel => 'Избери ги сите'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Споделете...'; @override String get tabSemanticsLabelRaw => r'Картичка $tabIndex од $tabCount'; @@ -8603,13 +8606,13 @@ class CupertinoLocalizationMl extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'തിരയുക'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'വെബിൽ തിരയുക'; @override String get selectAllButtonLabel => 'എല്ലാം തിരഞ്ഞെടുക്കുക'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'പങ്കിടുക...'; @override String get tabSemanticsLabelRaw => r'$tabCount ടാബിൽ $tabIndex-ാമത്തേത്'; @@ -8744,7 +8747,7 @@ class CupertinoLocalizationMn extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Дээшээ харах'; @override String get menuDismissLabel => 'Цэсийг хаах'; @@ -8765,13 +8768,13 @@ class CupertinoLocalizationMn extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Хайх'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Вебээс хайх'; @override String get selectAllButtonLabel => 'Бүгдийг сонгох'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Хуваалцах...'; @override String get tabSemanticsLabelRaw => r'$tabCount-н $tabIndex-р таб'; @@ -8906,7 +8909,7 @@ class CupertinoLocalizationMr extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'शोध घ्या'; @override String get menuDismissLabel => 'मेनू डिसमिस करा'; @@ -8927,13 +8930,13 @@ class CupertinoLocalizationMr extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'शोधा'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'वेबवर शोधा'; @override String get selectAllButtonLabel => 'सर्व निवडा'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'शेअर करा...'; @override String get tabSemanticsLabelRaw => r'$tabCount पैकी $tabIndex टॅब'; @@ -9089,13 +9092,13 @@ class CupertinoLocalizationMs extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Cari'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Buat carian pada Web'; @override String get selectAllButtonLabel => 'Pilih Semua'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Kongsi...'; @override String get tabSemanticsLabelRaw => r'Tab $tabIndex daripada $tabCount'; @@ -9230,7 +9233,7 @@ class CupertinoLocalizationMy extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'အပေါ်ကြည့်ရန်'; @override String get menuDismissLabel => 'မီနူးကိုပယ်ပါ'; @@ -9251,13 +9254,13 @@ class CupertinoLocalizationMy extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'ရှာရန်'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ဝဘ်တွင်ရှာရန်'; @override String get selectAllButtonLabel => 'အားလုံး ရွေးရန်'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'မျှဝေရန်...'; @override String get tabSemanticsLabelRaw => r'တဘ် $tabCount ခုအနက် $tabIndex ခု'; @@ -9392,7 +9395,7 @@ class CupertinoLocalizationNb extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Slå opp'; @override String get menuDismissLabel => 'Lukk menyen'; @@ -9413,13 +9416,13 @@ class CupertinoLocalizationNb extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Søk'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Søk på nettet'; @override String get selectAllButtonLabel => 'Velg alle'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Del…'; @override String get tabSemanticsLabelRaw => r'Fane $tabIndex av $tabCount'; @@ -9554,7 +9557,7 @@ class CupertinoLocalizationNe extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'माथितिर हेर्नुहोस्'; @override String get menuDismissLabel => 'मेनु खारेज गर्नुहोस्'; @@ -9575,13 +9578,13 @@ class CupertinoLocalizationNe extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'खोज्नुहोस्'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'वेबमा खोज्नुहोस्'; @override String get selectAllButtonLabel => 'सबै चयन गर्नुहोस्'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'सेयर गर्नुहोस्...'; @override String get tabSemanticsLabelRaw => r'$tabCount मध्ये $tabIndex ट्याब'; @@ -9716,7 +9719,7 @@ class CupertinoLocalizationNl extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Opzoeken'; @override String get menuDismissLabel => 'Menu sluiten'; @@ -9737,13 +9740,13 @@ class CupertinoLocalizationNl extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Zoeken'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Op internet zoeken'; @override String get selectAllButtonLabel => 'Alles selecteren'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Delen...'; @override String get tabSemanticsLabelRaw => r'Tabblad $tabIndex van $tabCount'; @@ -9878,7 +9881,7 @@ class CupertinoLocalizationNo extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Slå opp'; @override String get menuDismissLabel => 'Lukk menyen'; @@ -9899,13 +9902,13 @@ class CupertinoLocalizationNo extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Søk'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Søk på nettet'; @override String get selectAllButtonLabel => 'Velg alle'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Del…'; @override String get tabSemanticsLabelRaw => r'Fane $tabIndex av $tabCount'; @@ -10040,7 +10043,7 @@ class CupertinoLocalizationOr extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'ଉପରକୁ ଦେଖନ୍ତୁ'; @override String get menuDismissLabel => 'ମେନୁ ଖାରଜ କରନ୍ତୁ'; @@ -10061,13 +10064,13 @@ class CupertinoLocalizationOr extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'ସନ୍ଧାନ କରନ୍ତୁ'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ୱେବ ସର୍ଚ୍ଚ କରନ୍ତୁ'; @override String get selectAllButtonLabel => 'ସମସ୍ତ ଚୟନ କରନ୍ତୁ'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'ସେୟାର୍ କରନ୍ତୁ...'; @override String get tabSemanticsLabelRaw => r'$tabCountର $tabIndex ଟାବ୍'; @@ -10202,7 +10205,7 @@ class CupertinoLocalizationPa extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'ਖੋਜੋ'; @override String get menuDismissLabel => 'ਮੀਨੂ ਖਾਰਜ ਕਰੋ'; @@ -10223,13 +10226,13 @@ class CupertinoLocalizationPa extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'ਖੋਜੋ'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => "ਵੈੱਬ 'ਤੇ ਖੋਜੋ"; @override String get selectAllButtonLabel => 'ਸਭ ਚੁਣੋ'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'ਸਾਂਝਾ ਕਰੋ...'; @override String get tabSemanticsLabelRaw => r'$tabCount ਵਿੱਚੋਂ $tabIndex ਟੈਬ'; @@ -10385,13 +10388,13 @@ class CupertinoLocalizationPl extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Szukaj'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Szukaj w internecie'; @override String get selectAllButtonLabel => 'Wybierz wszystkie'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Udostępnij…'; @override String get tabSemanticsLabelRaw => r'Karta $tabIndex z $tabCount'; @@ -10547,13 +10550,13 @@ class CupertinoLocalizationPt extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Pesquisar'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Pesquisar na Web'; @override - String get selectAllButtonLabel => 'Selecionar Tudo'; + String get selectAllButtonLabel => 'Selecionar tudo'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Compartilhar…'; @override String get tabSemanticsLabelRaw => r'Guia $tabIndex de $tabCount'; @@ -10633,6 +10636,9 @@ class CupertinoLocalizationPtPt extends CupertinoLocalizationPt { required super.decimalFormat, }); + @override + String get shareButtonLabel => 'Partilhar…'; + @override String get lookUpButtonLabel => 'Procurar'; @@ -10657,9 +10663,6 @@ class CupertinoLocalizationPtPt extends CupertinoLocalizationPt { @override String get timerPickerSecondLabelOther => 'seg'; - @override - String get selectAllButtonLabel => 'Selecionar tudo'; - @override String get modalBarrierDismissLabel => 'Ignorar'; } @@ -10736,7 +10739,7 @@ class CupertinoLocalizationRo extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Privire în sus'; @override String get menuDismissLabel => 'Respingeți meniul'; @@ -10757,13 +10760,13 @@ class CupertinoLocalizationRo extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Căutați'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Căutați pe web'; @override - String get selectAllButtonLabel => 'Selectați-le pe toate'; + String get selectAllButtonLabel => 'Selectează tot'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Trimiteți…'; @override String get tabSemanticsLabelRaw => r'Fila $tabIndex din $tabCount'; @@ -10898,7 +10901,7 @@ class CupertinoLocalizationRu extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Найти'; @override String get menuDismissLabel => 'Закрыть меню'; @@ -10919,13 +10922,13 @@ class CupertinoLocalizationRu extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Поиск'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Искать в интернете'; @override String get selectAllButtonLabel => 'Выбрать все'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Поделиться'; @override String get tabSemanticsLabelRaw => r'Вкладка $tabIndex из $tabCount'; @@ -11060,7 +11063,7 @@ class CupertinoLocalizationSi extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'උඩ බලන්න'; @override String get menuDismissLabel => 'මෙනුව අස් කරන්න'; @@ -11081,13 +11084,13 @@ class CupertinoLocalizationSi extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'සෙවීම'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'වෙබය සොයන්න'; @override String get selectAllButtonLabel => 'සියල්ල තෝරන්න'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'බෙදා ගන්න...'; @override String get tabSemanticsLabelRaw => r'ටැබ $tabCount න් $tabIndex'; @@ -11222,7 +11225,7 @@ class CupertinoLocalizationSk extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Pohľad nahor'; @override String get menuDismissLabel => 'Zavrieť ponuku'; @@ -11243,13 +11246,13 @@ class CupertinoLocalizationSk extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Hľadať'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Hľadať na webe'; @override - String get selectAllButtonLabel => 'Vybrať všetko'; + String get selectAllButtonLabel => 'Označiť všetko'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Zdieľať…'; @override String get tabSemanticsLabelRaw => r'Karta $tabIndex z $tabCount'; @@ -11384,7 +11387,7 @@ class CupertinoLocalizationSl extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Pogled gor'; @override String get menuDismissLabel => 'Opusti meni'; @@ -11405,13 +11408,13 @@ class CupertinoLocalizationSl extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Iskanje'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Iskanje v spletu'; @override String get selectAllButtonLabel => 'Izberi vse'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Deli …'; @override String get tabSemanticsLabelRaw => r'Zavihek $tabIndex od $tabCount'; @@ -11546,7 +11549,7 @@ class CupertinoLocalizationSq extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Kërko'; @override String get menuDismissLabel => 'Hiqe menynë'; @@ -11567,13 +11570,13 @@ class CupertinoLocalizationSq extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Kërko'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Kërko në ueb'; @override String get selectAllButtonLabel => 'Zgjidhi të gjitha'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Ndaj...'; @override String get tabSemanticsLabelRaw => r'Skeda $tabIndex nga $tabCount'; @@ -11708,7 +11711,7 @@ class CupertinoLocalizationSr extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Поглед нагоре'; @override String get menuDismissLabel => 'Одбаците мени'; @@ -11729,13 +11732,13 @@ class CupertinoLocalizationSr extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Претражите'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Претражи веб'; @override String get selectAllButtonLabel => 'Изабери све'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Дели…'; @override String get tabSemanticsLabelRaw => r'$tabIndex. картица од $tabCount'; @@ -11863,6 +11866,9 @@ class CupertinoLocalizationSrLatn extends CupertinoLocalizationSr { @override String get datePickerMinuteSemanticsLabelOther => r'$minute minuta'; + @override + String get lookUpButtonLabel => 'Pogled nagore'; + @override String get menuDismissLabel => 'Odbacite meni'; @@ -11881,9 +11887,15 @@ class CupertinoLocalizationSrLatn extends CupertinoLocalizationSr { @override String get searchTextFieldPlaceholderLabel => 'Pretražite'; + @override + String get searchWebButtonLabel => 'Pretraži veb'; + @override String get selectAllButtonLabel => 'Izaberi sve'; + @override + String get shareButtonLabel => 'Deli…'; + @override String get tabSemanticsLabelRaw => r'$tabIndex. kartica od $tabCount'; @@ -11990,7 +12002,7 @@ class CupertinoLocalizationSv extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Titta upp'; @override String get menuDismissLabel => 'Stäng menyn'; @@ -12011,13 +12023,13 @@ class CupertinoLocalizationSv extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Sök'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Sök på webben'; @override - String get selectAllButtonLabel => 'Markera alla'; + String get selectAllButtonLabel => 'Markera allt'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Dela …'; @override String get tabSemanticsLabelRaw => r'Flik $tabIndex av $tabCount'; @@ -12152,7 +12164,7 @@ class CupertinoLocalizationSw extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Tafuta'; @override String get menuDismissLabel => 'Ondoa menyu'; @@ -12173,13 +12185,13 @@ class CupertinoLocalizationSw extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Tafuta'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Tafuta kwenye Wavuti'; @override String get selectAllButtonLabel => 'Teua Zote'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Shiriki...'; @override String get tabSemanticsLabelRaw => r'Kichupo cha $tabIndex kati ya $tabCount'; @@ -12314,7 +12326,7 @@ class CupertinoLocalizationTa extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'தேடு'; @override String get menuDismissLabel => 'மெனுவை மூடும்'; @@ -12335,13 +12347,13 @@ class CupertinoLocalizationTa extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'தேடுக'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'இணையத்தில் தேடு'; @override String get selectAllButtonLabel => 'எல்லாம் தேர்ந்தெடு'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'பகிர்...'; @override String get tabSemanticsLabelRaw => r'தாவல் $tabIndex / $tabCount'; @@ -12476,7 +12488,7 @@ class CupertinoLocalizationTe extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'వెతకండి'; @override String get menuDismissLabel => 'మెనూను తీసివేయండి'; @@ -12497,13 +12509,13 @@ class CupertinoLocalizationTe extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'సెర్చ్ చేయి'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'వెబ్‌లో సెర్చ్ చేయండి'; @override String get selectAllButtonLabel => 'అన్నింటినీ ఎంచుకోండి'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'షేర్ చేయండి...'; @override String get tabSemanticsLabelRaw => r'$tabCountలో $tabIndexవ ట్యాబ్'; @@ -12638,7 +12650,7 @@ class CupertinoLocalizationTh extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'ค้นหา'; @override String get menuDismissLabel => 'ปิดเมนู'; @@ -12659,13 +12671,13 @@ class CupertinoLocalizationTh extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'ค้นหา'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ค้นหาบนอินเทอร์เน็ต'; @override String get selectAllButtonLabel => 'เลือกทั้งหมด'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'แชร์...'; @override String get tabSemanticsLabelRaw => r'แท็บที่ $tabIndex จาก $tabCount'; @@ -12821,13 +12833,13 @@ class CupertinoLocalizationTl extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Hanapin'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Maghanap sa Web'; @override String get selectAllButtonLabel => 'Piliin Lahat'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Ibahagi...'; @override String get tabSemanticsLabelRaw => r'Tab $tabIndex ng $tabCount'; @@ -12962,7 +12974,7 @@ class CupertinoLocalizationTr extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Ara'; @override String get menuDismissLabel => 'Menüyü kapat'; @@ -12983,13 +12995,13 @@ class CupertinoLocalizationTr extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Ara'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => "Web'de Ara"; @override String get selectAllButtonLabel => 'Tümünü Seç'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Paylaş...'; @override String get tabSemanticsLabelRaw => r'Sekme $tabIndex/$tabCount'; @@ -13124,7 +13136,7 @@ class CupertinoLocalizationUk extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Шукати'; @override String get menuDismissLabel => 'Закрити меню'; @@ -13145,13 +13157,13 @@ class CupertinoLocalizationUk extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Шукайте'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Пошук в Інтернеті'; @override String get selectAllButtonLabel => 'Вибрати все'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Поділитися…'; @override String get tabSemanticsLabelRaw => r'Вкладка $tabIndex з $tabCount'; @@ -13286,7 +13298,7 @@ class CupertinoLocalizationUr extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'تفصیل دیکھیں'; @override String get menuDismissLabel => 'مینو برخاست کریں'; @@ -13307,13 +13319,13 @@ class CupertinoLocalizationUr extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'تلاش کریں'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ویب تلاش کریں'; @override String get selectAllButtonLabel => 'سبھی منتخب کریں'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'اشتراک کریں...'; @override String get tabSemanticsLabelRaw => r'$tabCount میں سے $tabIndex ٹیب'; @@ -13469,13 +13481,13 @@ class CupertinoLocalizationUz extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Qidiruv'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Internetdan qidirish'; @override String get selectAllButtonLabel => 'Barchasini tanlash'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Ulashish…'; @override String get tabSemanticsLabelRaw => r'$tabCount varaqdan $tabIndex'; @@ -13610,7 +13622,7 @@ class CupertinoLocalizationVi extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Tra cứu'; @override String get menuDismissLabel => 'Đóng trình đơn'; @@ -13631,13 +13643,13 @@ class CupertinoLocalizationVi extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Tìm kiếm'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Tìm kiếm trên web'; @override String get selectAllButtonLabel => 'Chọn tất cả'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Chia sẻ...'; @override String get tabSemanticsLabelRaw => r'Thẻ $tabIndex/$tabCount'; @@ -13772,7 +13784,7 @@ class CupertinoLocalizationZh extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => '向上看'; @override String get menuDismissLabel => '关闭菜单'; @@ -13793,13 +13805,13 @@ class CupertinoLocalizationZh extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => '搜索'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => '在网络上搜索'; @override String get selectAllButtonLabel => '全选'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => '分享…'; @override String get tabSemanticsLabelRaw => r'第 $tabIndex 个标签,共 $tabCount 个'; @@ -13939,6 +13951,9 @@ class CupertinoLocalizationZhHant extends CupertinoLocalizationZh { @override String get searchTextFieldPlaceholderLabel => '搜尋'; + @override + String get searchWebButtonLabel => '搜尋網頁'; + @override String get selectAllButtonLabel => '全選'; @@ -13993,6 +14008,9 @@ class CupertinoLocalizationZhHantTw extends CupertinoLocalizationZhHant { required super.decimalFormat, }); + @override + String get searchWebButtonLabel => '在網路上搜尋'; + @override String get noSpellCheckReplacementsLabel => '找不到替代文字'; @@ -14096,7 +14114,7 @@ class CupertinoLocalizationZu extends GlobalCupertinoLocalizations { String? get datePickerMinuteSemanticsLabelZero => null; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Bheka Phezulu'; @override String get menuDismissLabel => 'Chitha imenyu'; @@ -14117,13 +14135,13 @@ class CupertinoLocalizationZu extends GlobalCupertinoLocalizations { String get searchTextFieldPlaceholderLabel => 'Sesha'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Sesha Iwebhu'; @override String get selectAllButtonLabel => 'Khetha konke'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Yabelana...'; @override String get tabSemanticsLabelRaw => r'Ithebhu $tabIndex kwangu-$tabCount'; diff --git a/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart b/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart index f454b13b92810..583a57d470a48 100644 --- a/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart +++ b/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart @@ -330,7 +330,7 @@ class MaterialLocalizationAf extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Lisensies'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Kyk op'; @override String get menuBarMenuLabel => 'Kieslysbalkkieslys'; @@ -438,7 +438,7 @@ class MaterialLocalizationAf extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Soek'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Deursoek web'; @override String get selectAllButtonLabel => 'Kies alles'; @@ -465,7 +465,7 @@ class MaterialLocalizationAf extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Deel …'; @override String get showAccountsLabel => 'Wys rekeninge'; @@ -820,7 +820,7 @@ class MaterialLocalizationAm extends GlobalMaterialLocalizations { String get licensesPageTitle => 'ፈቃዶች'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'ይመልከቱ'; @override String get menuBarMenuLabel => 'የምናሌ አሞሌ ምናሌ'; @@ -928,7 +928,7 @@ class MaterialLocalizationAm extends GlobalMaterialLocalizations { String get searchFieldLabel => 'ይፈልጉ'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ድርን ፈልግ'; @override String get selectAllButtonLabel => 'ሁሉንም ምረጥ'; @@ -955,7 +955,7 @@ class MaterialLocalizationAm extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'አጋራ...'; @override String get showAccountsLabel => 'መለያዎችን አሳይ'; @@ -1310,7 +1310,7 @@ class MaterialLocalizationAr extends GlobalMaterialLocalizations { String get licensesPageTitle => 'التراخيص'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'النظر إلى أعلى'; @override String get menuBarMenuLabel => 'قائمة شريط القوائم'; @@ -1418,7 +1418,7 @@ class MaterialLocalizationAr extends GlobalMaterialLocalizations { String get searchFieldLabel => 'بحث'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'البحث على الويب'; @override String get selectAllButtonLabel => 'اختيار الكل'; @@ -1445,7 +1445,7 @@ class MaterialLocalizationAr extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'لم يتم اختيار أي عنصر'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'مشاركة…'; @override String get showAccountsLabel => 'إظهار الحسابات'; @@ -1800,7 +1800,7 @@ class MaterialLocalizationAs extends GlobalMaterialLocalizations { String get licensesPageTitle => 'অনুজ্ঞাপত্ৰসমূহ'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'ওপৰলৈ চাওক'; @override String get menuBarMenuLabel => 'মেনু বাৰ মেনু'; @@ -1908,7 +1908,7 @@ class MaterialLocalizationAs extends GlobalMaterialLocalizations { String get searchFieldLabel => 'সন্ধান কৰক'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ৱেবত সন্ধান কৰক'; @override String get selectAllButtonLabel => 'সকলো বাছনি কৰক'; @@ -1935,7 +1935,7 @@ class MaterialLocalizationAs extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'শ্বেয়াৰ কৰক…'; @override String get showAccountsLabel => 'একাউণ্টসমূহ দেখুৱাওক'; @@ -2290,7 +2290,7 @@ class MaterialLocalizationAz extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Lisenziyalar'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Axtarın'; @override String get menuBarMenuLabel => 'Menyu paneli menyusu'; @@ -2398,7 +2398,7 @@ class MaterialLocalizationAz extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Axtarın'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Vebdə axtarın'; @override String get selectAllButtonLabel => 'Hamısını seçin'; @@ -2425,7 +2425,7 @@ class MaterialLocalizationAz extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Paylaşın...'; @override String get showAccountsLabel => 'Hesabları göstərin'; @@ -2780,7 +2780,7 @@ class MaterialLocalizationBe extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Ліцэнзіі'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Знайсці'; @override String get menuBarMenuLabel => 'Меню "Панэль меню"'; @@ -2888,7 +2888,7 @@ class MaterialLocalizationBe extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Пошук'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Пошук у сетцы'; @override String get selectAllButtonLabel => 'Выбраць усе'; @@ -2915,7 +2915,7 @@ class MaterialLocalizationBe extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Абагуліць...'; @override String get showAccountsLabel => 'Паказаць уліковыя запісы'; @@ -3378,7 +3378,7 @@ class MaterialLocalizationBg extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Търсене'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Търсене в мрежата'; @override String get selectAllButtonLabel => 'Избиране на всички'; @@ -3405,7 +3405,7 @@ class MaterialLocalizationBg extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Споделяне...'; @override String get showAccountsLabel => 'Показване на профилите'; @@ -3760,7 +3760,7 @@ class MaterialLocalizationBn extends GlobalMaterialLocalizations { String get licensesPageTitle => 'লাইসেন্স'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'লুক-আপ'; @override String get menuBarMenuLabel => 'মেনু বার মেনু'; @@ -3868,7 +3868,7 @@ class MaterialLocalizationBn extends GlobalMaterialLocalizations { String get searchFieldLabel => 'খুঁজুন'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ওয়েবে সার্চ করুন'; @override String get selectAllButtonLabel => 'সব বেছে নিন'; @@ -3895,7 +3895,7 @@ class MaterialLocalizationBn extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'শেয়ার করুন...'; @override String get showAccountsLabel => 'অ্যাকাউন্টগুলি দেখান'; @@ -4250,7 +4250,7 @@ class MaterialLocalizationBs extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Licence'; @override - String get lookUpButtonLabel => 'Pogled prema gore'; + String get lookUpButtonLabel => 'Pogled nagore'; @override String get menuBarMenuLabel => 'Meni trake menija'; @@ -4358,7 +4358,7 @@ class MaterialLocalizationBs extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Pretražite'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Pretraži Web'; @override String get selectAllButtonLabel => 'Odaberi sve'; @@ -4385,7 +4385,7 @@ class MaterialLocalizationBs extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Dijeli...'; @override String get showAccountsLabel => 'Prikaži račune'; @@ -4740,7 +4740,7 @@ class MaterialLocalizationCa extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Llicències'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Mira amunt'; @override String get menuBarMenuLabel => 'Menú de la barra de menú'; @@ -4848,7 +4848,7 @@ class MaterialLocalizationCa extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Cerca'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Cerca al web'; @override String get selectAllButtonLabel => 'Selecciona-ho tot'; @@ -4875,7 +4875,7 @@ class MaterialLocalizationCa extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Comparteix...'; @override String get showAccountsLabel => 'Mostra els comptes'; @@ -5230,7 +5230,7 @@ class MaterialLocalizationCs extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Licence'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Vyhledat'; @override String get menuBarMenuLabel => 'Nabídka na liště s nabídkou'; @@ -5338,7 +5338,7 @@ class MaterialLocalizationCs extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Hledat'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Vyhledávat na webu'; @override String get selectAllButtonLabel => 'Vybrat vše'; @@ -5365,7 +5365,7 @@ class MaterialLocalizationCs extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Sdílet…'; @override String get showAccountsLabel => 'Zobrazit účty'; @@ -5720,7 +5720,7 @@ class MaterialLocalizationCy extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Trwyddedau'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Chwilio'; @override String get menuBarMenuLabel => 'Dewislen bar dewislen'; @@ -5828,7 +5828,7 @@ class MaterialLocalizationCy extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Chwilio'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => "Chwilio'r We"; @override String get selectAllButtonLabel => 'Dewis y Cyfan'; @@ -5855,7 +5855,7 @@ class MaterialLocalizationCy extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => "Nid oes unrhyw eitemau wedi'u dewis"; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Rhannu...'; @override String get showAccountsLabel => 'Dangos cyfrifon'; @@ -6210,7 +6210,7 @@ class MaterialLocalizationDa extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Licenser'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Slå op'; @override String get menuBarMenuLabel => 'Menuen for menulinjen'; @@ -6318,7 +6318,7 @@ class MaterialLocalizationDa extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Søg'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Søg på nettet'; @override String get selectAllButtonLabel => 'Markér alt'; @@ -6345,7 +6345,7 @@ class MaterialLocalizationDa extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Del…'; @override String get showAccountsLabel => 'Vis konti'; @@ -6700,7 +6700,7 @@ class MaterialLocalizationDe extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Lizenzen'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Nachschlagen'; @override String get menuBarMenuLabel => 'Menü in der Menüleiste'; @@ -6808,7 +6808,7 @@ class MaterialLocalizationDe extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Suchen'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Im Web suchen'; @override String get selectAllButtonLabel => 'Alle auswählen'; @@ -6835,7 +6835,7 @@ class MaterialLocalizationDe extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'Keine Objekte ausgewählt'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Teilen…'; @override String get showAccountsLabel => 'Konten anzeigen'; @@ -7362,7 +7362,7 @@ class MaterialLocalizationEl extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Αναζήτηση'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Αναζήτηση στον ιστό'; @override String get selectAllButtonLabel => 'Επιλογή όλων'; @@ -7389,7 +7389,7 @@ class MaterialLocalizationEl extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Κοινοποίηση…'; @override String get showAccountsLabel => 'Εμφάνιση λογαριασμών'; @@ -9031,7 +9031,7 @@ class MaterialLocalizationEs extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Licencias'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Buscador visual'; @override String get menuBarMenuLabel => 'Menú de la barra de menú'; @@ -9139,7 +9139,7 @@ class MaterialLocalizationEs extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Buscar'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Buscar en la Web'; @override String get selectAllButtonLabel => 'Seleccionar todo'; @@ -9166,7 +9166,7 @@ class MaterialLocalizationEs extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'No se han seleccionado elementos'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Compartir...'; @override String get showAccountsLabel => 'Mostrar cuentas'; @@ -9229,6 +9229,9 @@ class MaterialLocalizationEs419 extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -9419,6 +9422,9 @@ class MaterialLocalizationEsAr extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -9609,6 +9615,9 @@ class MaterialLocalizationEsBo extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -9799,6 +9808,9 @@ class MaterialLocalizationEsCl extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -9989,6 +10001,9 @@ class MaterialLocalizationEsCo extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -10179,6 +10194,9 @@ class MaterialLocalizationEsCr extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -10369,6 +10387,9 @@ class MaterialLocalizationEsDo extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -10559,6 +10580,9 @@ class MaterialLocalizationEsEc extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -10749,6 +10773,9 @@ class MaterialLocalizationEsGt extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -10939,6 +10966,9 @@ class MaterialLocalizationEsHn extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -11129,6 +11159,9 @@ class MaterialLocalizationEsMx extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -11319,6 +11352,9 @@ class MaterialLocalizationEsNi extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -11509,6 +11545,9 @@ class MaterialLocalizationEsPa extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -11699,6 +11738,9 @@ class MaterialLocalizationEsPe extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -11889,6 +11931,9 @@ class MaterialLocalizationEsPr extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -12079,6 +12124,9 @@ class MaterialLocalizationEsPy extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -12269,6 +12317,9 @@ class MaterialLocalizationEsSv extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -12459,6 +12510,9 @@ class MaterialLocalizationEsUs extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -12652,6 +12706,9 @@ class MaterialLocalizationEsUy extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -12842,6 +12899,9 @@ class MaterialLocalizationEsVe extends MaterialLocalizationEs { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Compartir…'; + @override String get scanTextButtonLabel => 'Analizar texto'; @@ -13432,7 +13492,7 @@ class MaterialLocalizationEt extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Otsing'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Otsi veebist'; @override String get selectAllButtonLabel => 'Vali kõik'; @@ -13459,7 +13519,7 @@ class MaterialLocalizationEt extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Jaga …'; @override String get showAccountsLabel => 'Kuva kontod'; @@ -13814,7 +13874,7 @@ class MaterialLocalizationEu extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Lizentziak'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Bilatu'; @override String get menuBarMenuLabel => 'Menu-barraren menua'; @@ -13922,7 +13982,7 @@ class MaterialLocalizationEu extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Bilatu'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Bilatu sarean'; @override String get selectAllButtonLabel => 'Hautatu guztiak'; @@ -13949,7 +14009,7 @@ class MaterialLocalizationEu extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Partekatu...'; @override String get showAccountsLabel => 'Erakutsi kontuak'; @@ -14304,7 +14364,7 @@ class MaterialLocalizationFa extends GlobalMaterialLocalizations { String get licensesPageTitle => 'پروانه‌ها'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'جستجو'; @override String get menuBarMenuLabel => 'منوی نوار منو'; @@ -14412,7 +14472,7 @@ class MaterialLocalizationFa extends GlobalMaterialLocalizations { String get searchFieldLabel => 'جستجو'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'جستجو در وب'; @override String get selectAllButtonLabel => 'انتخاب همه'; @@ -14439,7 +14499,7 @@ class MaterialLocalizationFa extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'هم‌رسانی…'; @override String get showAccountsLabel => 'نشان دادن حساب‌ها'; @@ -14794,7 +14854,7 @@ class MaterialLocalizationFi extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Lisenssit'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Hae'; @override String get menuBarMenuLabel => 'Valikkopalkki'; @@ -14902,7 +14962,7 @@ class MaterialLocalizationFi extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Haku'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Hae verkosta'; @override String get selectAllButtonLabel => 'Valitse kaikki'; @@ -14929,7 +14989,7 @@ class MaterialLocalizationFi extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Jaa…'; @override String get showAccountsLabel => 'Näytä tilit'; @@ -15392,7 +15452,7 @@ class MaterialLocalizationFil extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Maghanap'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Maghanap sa Web'; @override String get selectAllButtonLabel => 'Piliin lahat'; @@ -15419,7 +15479,7 @@ class MaterialLocalizationFil extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Ibahagi...'; @override String get showAccountsLabel => 'Ipakita ang mga account'; @@ -15774,7 +15834,7 @@ class MaterialLocalizationFr extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Licences'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Recherche visuelle'; @override String get menuBarMenuLabel => 'Menu de la barre de menu'; @@ -15882,7 +15942,7 @@ class MaterialLocalizationFr extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Rechercher'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Rechercher sur le Web'; @override String get selectAllButtonLabel => 'Tout sélectionner'; @@ -15909,7 +15969,7 @@ class MaterialLocalizationFr extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'Aucun élément sélectionné'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Partager…'; @override String get showAccountsLabel => 'Afficher les comptes'; @@ -15972,6 +16032,9 @@ class MaterialLocalizationFrCa extends MaterialLocalizationFr { required super.twoDigitZeroPaddedFormat, }); + @override + String get lookUpButtonLabel => 'Regarder en haut'; + @override String get scanTextButtonLabel => 'Balayer un texte'; @@ -16529,7 +16592,7 @@ class MaterialLocalizationGl extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Buscar'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Buscar na Web'; @override String get selectAllButtonLabel => 'Seleccionar todo'; @@ -16556,7 +16619,7 @@ class MaterialLocalizationGl extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'Non se seleccionaron elementos'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Compartir…'; @override String get showAccountsLabel => 'Mostrar contas'; @@ -16911,7 +16974,7 @@ class MaterialLocalizationGsw extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Lizenzen'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Nachschlagen'; @override String get menuBarMenuLabel => 'Menü in der Menüleiste'; @@ -17019,7 +17082,7 @@ class MaterialLocalizationGsw extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Suchen'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Im Web suchen'; @override String get selectAllButtonLabel => 'Alle auswählen'; @@ -17046,7 +17109,7 @@ class MaterialLocalizationGsw extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Teilen…'; @override String get showAccountsLabel => 'Konten anzeigen'; @@ -17401,7 +17464,7 @@ class MaterialLocalizationGu extends GlobalMaterialLocalizations { String get licensesPageTitle => 'લાઇસન્સ'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'શોધો'; @override String get menuBarMenuLabel => 'મેનૂ બાર મેનૂ'; @@ -17509,7 +17572,7 @@ class MaterialLocalizationGu extends GlobalMaterialLocalizations { String get searchFieldLabel => 'શોધો'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'વેબ પર શોધો'; @override String get selectAllButtonLabel => 'બધા પસંદ કરો'; @@ -17536,7 +17599,7 @@ class MaterialLocalizationGu extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'શેર કરો…'; @override String get showAccountsLabel => 'એકાઉન્ટ બતાવો'; @@ -17891,7 +17954,7 @@ class MaterialLocalizationHe extends GlobalMaterialLocalizations { String get licensesPageTitle => 'רישיונות'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'חיפוש'; @override String get menuBarMenuLabel => 'תפריט בסרגל התפריטים'; @@ -17999,7 +18062,7 @@ class MaterialLocalizationHe extends GlobalMaterialLocalizations { String get searchFieldLabel => 'חיפוש'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'חיפוש באינטרנט'; @override String get selectAllButtonLabel => 'בחירת הכול'; @@ -18026,7 +18089,7 @@ class MaterialLocalizationHe extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'שיתוף…'; @override String get showAccountsLabel => 'הצגת החשבונות'; @@ -18381,7 +18444,7 @@ class MaterialLocalizationHi extends GlobalMaterialLocalizations { String get licensesPageTitle => 'लाइसेंस'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'लुक अप बटन'; @override String get menuBarMenuLabel => 'मेन्यू बार का मेन्यू'; @@ -18489,7 +18552,7 @@ class MaterialLocalizationHi extends GlobalMaterialLocalizations { String get searchFieldLabel => 'खोजें'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'वेब पर खोजें'; @override String get selectAllButtonLabel => 'सभी को चुनें'; @@ -18516,7 +18579,7 @@ class MaterialLocalizationHi extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'शेयर करें…'; @override String get showAccountsLabel => 'खाते दिखाएं'; @@ -18979,7 +19042,7 @@ class MaterialLocalizationHr extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Pretražite'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Pretraži web'; @override String get selectAllButtonLabel => 'Odaberi sve'; @@ -19006,7 +19069,7 @@ class MaterialLocalizationHr extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Dijeli...'; @override String get showAccountsLabel => 'Prikažite račune'; @@ -19469,7 +19532,7 @@ class MaterialLocalizationHu extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Keresés'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Keresés az interneten'; @override String get selectAllButtonLabel => 'Összes kijelölése'; @@ -19496,7 +19559,7 @@ class MaterialLocalizationHu extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Megosztás…'; @override String get showAccountsLabel => 'Fiókok megjelenítése'; @@ -19851,7 +19914,7 @@ class MaterialLocalizationHy extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Արտոնագրեր'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Փնտրել'; @override String get menuBarMenuLabel => 'Ընտրացանկի գոտու ընտրացանկ'; @@ -19959,7 +20022,7 @@ class MaterialLocalizationHy extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Որոնել'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Որոնել համացանցում'; @override String get selectAllButtonLabel => 'Նշել բոլորը'; @@ -19986,7 +20049,7 @@ class MaterialLocalizationHy extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'Տողերը ընտրված չեն'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Կիսվել...'; @override String get showAccountsLabel => 'Ցույց տալ հաշիվները'; @@ -20341,7 +20404,7 @@ class MaterialLocalizationId extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Lisensi'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Cari'; @override String get menuBarMenuLabel => 'Menu panel menu'; @@ -20449,7 +20512,7 @@ class MaterialLocalizationId extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Telusuri'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Telusuri di Web'; @override String get selectAllButtonLabel => 'Pilih semua'; @@ -20476,7 +20539,7 @@ class MaterialLocalizationId extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Bagikan...'; @override String get showAccountsLabel => 'Tampilkan akun'; @@ -20939,7 +21002,7 @@ class MaterialLocalizationIs extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Leit'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Leita á vefnum'; @override String get selectAllButtonLabel => 'Velja allt'; @@ -20966,7 +21029,7 @@ class MaterialLocalizationIs extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Deila...'; @override String get showAccountsLabel => 'Sýna reikninga'; @@ -21429,7 +21492,7 @@ class MaterialLocalizationIt extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Cerca'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Cerca sul web'; @override String get selectAllButtonLabel => 'Seleziona tutto'; @@ -21456,7 +21519,7 @@ class MaterialLocalizationIt extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Condividi…'; @override String get showAccountsLabel => 'Mostra account'; @@ -21919,10 +21982,10 @@ class MaterialLocalizationJa extends GlobalMaterialLocalizations { String get searchFieldLabel => '検索'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ウェブを検索'; @override - String get selectAllButtonLabel => 'すべて選択'; + String get selectAllButtonLabel => 'すべてを選択'; @override String get selectYearSemanticsLabel => '年を選択'; @@ -21946,7 +22009,7 @@ class MaterialLocalizationJa extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => '共有...'; @override String get showAccountsLabel => 'アカウントを表示'; @@ -22301,7 +22364,7 @@ class MaterialLocalizationKa extends GlobalMaterialLocalizations { String get licensesPageTitle => 'ლიცენზიები'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'აიხედეთ ზემოთ'; @override String get menuBarMenuLabel => 'მენიუს ზოლის მენიუ'; @@ -22409,7 +22472,7 @@ class MaterialLocalizationKa extends GlobalMaterialLocalizations { String get searchFieldLabel => 'ძიება'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ვებში ძიება'; @override String get selectAllButtonLabel => 'ყველას არჩევა'; @@ -22436,7 +22499,7 @@ class MaterialLocalizationKa extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'გაზიარება...'; @override String get showAccountsLabel => 'ანგარიშების ჩვენება'; @@ -22791,7 +22854,7 @@ class MaterialLocalizationKk extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Лицензиялар'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Іздеу'; @override String get menuBarMenuLabel => 'Мәзір жолағының мәзірі'; @@ -22899,7 +22962,7 @@ class MaterialLocalizationKk extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Іздеу'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Интернеттен іздеу'; @override String get selectAllButtonLabel => 'Барлығын таңдау'; @@ -22926,7 +22989,7 @@ class MaterialLocalizationKk extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'Тармақ таңдалмаған'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Бөлісу…'; @override String get showAccountsLabel => 'Аккаунттарды көрсету'; @@ -23389,7 +23452,7 @@ class MaterialLocalizationKm extends GlobalMaterialLocalizations { String get searchFieldLabel => 'ស្វែងរក'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ស្វែងរក​លើបណ្ដាញ'; @override String get selectAllButtonLabel => 'ជ្រើសរើស​ទាំងអស់'; @@ -23416,7 +23479,7 @@ class MaterialLocalizationKm extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'ចែករំលែក...'; @override String get showAccountsLabel => 'បង្ហាញគណនី'; @@ -23771,7 +23834,7 @@ class MaterialLocalizationKn extends GlobalMaterialLocalizations { String get licensesPageTitle => '\u{caa}\u{cb0}\u{cb5}\u{cbe}\u{ca8}\u{c97}\u{cbf}\u{c97}\u{cb3}\u{cc1}'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => '\u{cae}\u{cc7}\u{cb2}\u{cc6}\u{20}\u{ca8}\u{ccb}\u{ca1}\u{cbf}'; @override String get menuBarMenuLabel => '\u{cae}\u{cc6}\u{ca8}\u{cc1}\u{20}\u{cac}\u{cbe}\u{cb0}\u{ccd}\u{200c}\u{20}\u{cae}\u{cc6}\u{ca8}\u{cc1}'; @@ -23879,7 +23942,7 @@ class MaterialLocalizationKn extends GlobalMaterialLocalizations { String get searchFieldLabel => '\u{cb9}\u{cc1}\u{ca1}\u{cc1}\u{c95}\u{cbf}'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => '\u{cb5}\u{cc6}\u{cac}\u{ccd}\u{200c}\u{ca8}\u{cb2}\u{ccd}\u{cb2}\u{cbf}\u{20}\u{cb9}\u{cc1}\u{ca1}\u{cc1}\u{c95}\u{cbf}'; @override String get selectAllButtonLabel => '\u{c8e}\u{cb2}\u{ccd}\u{cb2}\u{cb5}\u{ca8}\u{ccd}\u{ca8}\u{cc2}\u{20}\u{c86}\u{caf}\u{ccd}\u{c95}\u{cc6}\u{20}\u{cae}\u{cbe}\u{ca1}\u{cbf}'; @@ -23906,7 +23969,7 @@ class MaterialLocalizationKn extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => '\u{cb9}\u{c82}\u{c9a}\u{cbf}\u{c95}\u{cca}\u{cb3}\u{ccd}\u{cb3}\u{cbf}\u{2e}\u{2e}\u{2e}'; @override String get showAccountsLabel => '\u{c96}\u{cbe}\u{ca4}\u{cc6}\u{c97}\u{cb3}\u{ca8}\u{ccd}\u{ca8}\u{cc1}\u{20}\u{ca4}\u{ccb}\u{cb0}\u{cbf}\u{cb8}\u{cbf}'; @@ -24261,7 +24324,7 @@ class MaterialLocalizationKo extends GlobalMaterialLocalizations { String get licensesPageTitle => '라이선스'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => '찾기'; @override String get menuBarMenuLabel => '메뉴 바 메뉴'; @@ -24369,7 +24432,7 @@ class MaterialLocalizationKo extends GlobalMaterialLocalizations { String get searchFieldLabel => '검색'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => '웹 검색'; @override String get selectAllButtonLabel => '전체 선택'; @@ -24396,7 +24459,7 @@ class MaterialLocalizationKo extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => '공유...'; @override String get showAccountsLabel => '계정 표시'; @@ -24751,7 +24814,7 @@ class MaterialLocalizationKy extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Уруксаттамалар'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Издөө'; @override String get menuBarMenuLabel => 'Меню тилкеси менюсу'; @@ -24859,7 +24922,7 @@ class MaterialLocalizationKy extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Издөө'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Интернеттен издөө'; @override String get selectAllButtonLabel => 'Баарын тандоо'; @@ -24886,7 +24949,7 @@ class MaterialLocalizationKy extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Бөлүшүү…'; @override String get showAccountsLabel => 'Аккаунттарды көрсөтүү'; @@ -25241,7 +25304,7 @@ class MaterialLocalizationLo extends GlobalMaterialLocalizations { String get licensesPageTitle => 'ໃບອະນຸຍາດ'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'ຊອກຫາຂໍ້ມູນ'; @override String get menuBarMenuLabel => 'ເມນູແຖບເມນູ'; @@ -25349,7 +25412,7 @@ class MaterialLocalizationLo extends GlobalMaterialLocalizations { String get searchFieldLabel => 'ຊອກຫາ'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ຊອກຫາຢູ່ອິນເຕີເນັດ'; @override String get selectAllButtonLabel => 'ເລືອກທັງໝົດ'; @@ -25376,7 +25439,7 @@ class MaterialLocalizationLo extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'ແບ່ງປັນ...'; @override String get showAccountsLabel => 'ສະແດງບັນຊີ'; @@ -25731,7 +25794,7 @@ class MaterialLocalizationLt extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Licencijos'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Ieškoti'; @override String get menuBarMenuLabel => 'Meniu juostos meniu'; @@ -25839,7 +25902,7 @@ class MaterialLocalizationLt extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Paieška'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Ieškoti žiniatinklyje'; @override String get selectAllButtonLabel => 'Pasirinkti viską'; @@ -25866,7 +25929,7 @@ class MaterialLocalizationLt extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Bendrinti...'; @override String get showAccountsLabel => 'Rodyti paskyras'; @@ -26221,7 +26284,7 @@ class MaterialLocalizationLv extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Licences'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Meklēt'; @override String get menuBarMenuLabel => 'Izvēļņu joslas izvēlne'; @@ -26329,7 +26392,7 @@ class MaterialLocalizationLv extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Meklēt'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Meklēt tīmeklī'; @override String get selectAllButtonLabel => 'Atlasīt visu'; @@ -26356,7 +26419,7 @@ class MaterialLocalizationLv extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'Nav atlasītu vienumu'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Kopīgot…'; @override String get showAccountsLabel => 'Rādīt kontus'; @@ -26711,7 +26774,7 @@ class MaterialLocalizationMk extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Лиценци'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Погледнете нагоре'; @override String get menuBarMenuLabel => 'Мени на лентата со мени'; @@ -26819,7 +26882,7 @@ class MaterialLocalizationMk extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Пребарувајте'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Пребарајте на интернет'; @override String get selectAllButtonLabel => 'Избери ги сите'; @@ -26846,7 +26909,7 @@ class MaterialLocalizationMk extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Споделете...'; @override String get showAccountsLabel => 'Прикажи сметки'; @@ -27309,7 +27372,7 @@ class MaterialLocalizationMl extends GlobalMaterialLocalizations { String get searchFieldLabel => 'തിരയുക'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'വെബിൽ തിരയുക'; @override String get selectAllButtonLabel => 'എല്ലാം തിരഞ്ഞെടുക്കുക'; @@ -27336,7 +27399,7 @@ class MaterialLocalizationMl extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'പങ്കിടുക...'; @override String get showAccountsLabel => 'അക്കൗണ്ടുകൾ കാണിക്കുക'; @@ -27691,7 +27754,7 @@ class MaterialLocalizationMn extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Лиценз'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Дээшээ харах'; @override String get menuBarMenuLabel => 'Цэсний талбарын цэс'; @@ -27799,7 +27862,7 @@ class MaterialLocalizationMn extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Хайх'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Вебээс хайх'; @override String get selectAllButtonLabel => 'Бүгдийг сонгох'; @@ -27826,7 +27889,7 @@ class MaterialLocalizationMn extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'Бичлэг сонгоогүй байна'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Хуваалцах...'; @override String get showAccountsLabel => 'Бүртгэлүүдийг харуулах'; @@ -28181,7 +28244,7 @@ class MaterialLocalizationMr extends GlobalMaterialLocalizations { String get licensesPageTitle => 'परवाने'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'शोध घ्या'; @override String get menuBarMenuLabel => 'मेनू बार मेनू'; @@ -28289,7 +28352,7 @@ class MaterialLocalizationMr extends GlobalMaterialLocalizations { String get searchFieldLabel => 'शोध'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'वेबवर शोधा'; @override String get selectAllButtonLabel => 'सर्व निवडा'; @@ -28316,7 +28379,7 @@ class MaterialLocalizationMr extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'कोणतेही आयटम निवडलेले नाहीत'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'शेअर करा...'; @override String get showAccountsLabel => 'खाती दर्शवा'; @@ -28779,7 +28842,7 @@ class MaterialLocalizationMs extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Cari'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Buat carian pada Web'; @override String get selectAllButtonLabel => 'Pilih semua'; @@ -28806,7 +28869,7 @@ class MaterialLocalizationMs extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'Tiada item dipilih'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Kongsi...'; @override String get showAccountsLabel => 'Tunjukkan akaun'; @@ -29161,7 +29224,7 @@ class MaterialLocalizationMy extends GlobalMaterialLocalizations { String get licensesPageTitle => 'လိုင်စင်များ'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'အပေါ်ကြည့်ရန်'; @override String get menuBarMenuLabel => 'မီနူးဘား မီနူး'; @@ -29269,7 +29332,7 @@ class MaterialLocalizationMy extends GlobalMaterialLocalizations { String get searchFieldLabel => 'ရှာဖွေရန်'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ဝဘ်တွင်ရှာရန်'; @override String get selectAllButtonLabel => 'အားလုံး ရွေးရန်'; @@ -29296,7 +29359,7 @@ class MaterialLocalizationMy extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'မျှဝေရန်...'; @override String get showAccountsLabel => 'အကောင့်များကို ပြရန်'; @@ -29651,7 +29714,7 @@ class MaterialLocalizationNb extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Lisenser'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Slå opp'; @override String get menuBarMenuLabel => 'Meny med menylinje'; @@ -29759,7 +29822,7 @@ class MaterialLocalizationNb extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Søk'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Søk på nettet'; @override String get selectAllButtonLabel => 'Velg alle'; @@ -29786,7 +29849,7 @@ class MaterialLocalizationNb extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Del…'; @override String get showAccountsLabel => 'Vis kontoer'; @@ -30141,7 +30204,7 @@ class MaterialLocalizationNe extends GlobalMaterialLocalizations { String get licensesPageTitle => 'इजाजतपत्रहरू'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'माथितिर हेर्नुहोस्'; @override String get menuBarMenuLabel => '"मेनु बार" मेनु'; @@ -30249,7 +30312,7 @@ class MaterialLocalizationNe extends GlobalMaterialLocalizations { String get searchFieldLabel => 'खोज्नुहोस्'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'वेबमा खोज्नुहोस्'; @override String get selectAllButtonLabel => 'सबै बटनहरू चयन गर्नुहोस्'; @@ -30276,7 +30339,7 @@ class MaterialLocalizationNe extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'सेयर गर्नुहोस्...'; @override String get showAccountsLabel => 'खाताहरू देखाउनुहोस्'; @@ -30631,7 +30694,7 @@ class MaterialLocalizationNl extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Licenties'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Opzoeken'; @override String get menuBarMenuLabel => 'Menu van menubalk'; @@ -30739,7 +30802,7 @@ class MaterialLocalizationNl extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Zoeken'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Op internet zoeken'; @override String get selectAllButtonLabel => 'Alles selecteren'; @@ -30766,7 +30829,7 @@ class MaterialLocalizationNl extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Delen...'; @override String get showAccountsLabel => 'Accounts tonen'; @@ -31121,7 +31184,7 @@ class MaterialLocalizationNo extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Lisenser'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Slå opp'; @override String get menuBarMenuLabel => 'Meny med menylinje'; @@ -31229,7 +31292,7 @@ class MaterialLocalizationNo extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Søk'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Søk på nettet'; @override String get selectAllButtonLabel => 'Velg alle'; @@ -31256,7 +31319,7 @@ class MaterialLocalizationNo extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Del…'; @override String get showAccountsLabel => 'Vis kontoer'; @@ -31611,7 +31674,7 @@ class MaterialLocalizationOr extends GlobalMaterialLocalizations { String get licensesPageTitle => 'ଲାଇସେନ୍ସଗୁଡ଼କ'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'ଉପରକୁ ଦେଖନ୍ତୁ'; @override String get menuBarMenuLabel => 'ମେନୁ ବାର ମେନୁ'; @@ -31719,7 +31782,7 @@ class MaterialLocalizationOr extends GlobalMaterialLocalizations { String get searchFieldLabel => 'ସନ୍ଧାନ କରନ୍ତୁ'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ୱେବ ସର୍ଚ୍ଚ କରନ୍ତୁ'; @override String get selectAllButtonLabel => 'ସବୁ ଚୟନ କରନ୍ତୁ'; @@ -31746,7 +31809,7 @@ class MaterialLocalizationOr extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'ସେୟାର୍ କରନ୍ତୁ...'; @override String get showAccountsLabel => 'ଆକାଉଣ୍ଟ ଦେଖାନ୍ତୁ'; @@ -32101,7 +32164,7 @@ class MaterialLocalizationPa extends GlobalMaterialLocalizations { String get licensesPageTitle => 'ਲਾਇਸੰਸ'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'ਖੋਜੋ'; @override String get menuBarMenuLabel => 'ਮੀਨੂ ਬਾਰ ਮੀਨੂ'; @@ -32209,7 +32272,7 @@ class MaterialLocalizationPa extends GlobalMaterialLocalizations { String get searchFieldLabel => 'ਖੋਜੋ'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => "ਵੈੱਬ 'ਤੇ ਖੋਜੋ"; @override String get selectAllButtonLabel => 'ਸਭ ਚੁਣੋ'; @@ -32236,7 +32299,7 @@ class MaterialLocalizationPa extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'ਸਾਂਝਾ ਕਰੋ...'; @override String get showAccountsLabel => 'ਖਾਤੇ ਦਿਖਾਓ'; @@ -32699,7 +32762,7 @@ class MaterialLocalizationPl extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Szukaj'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Szukaj w internecie'; @override String get selectAllButtonLabel => 'Zaznacz wszystko'; @@ -32726,7 +32789,7 @@ class MaterialLocalizationPl extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Udostępnij…'; @override String get showAccountsLabel => 'Pokaż konta'; @@ -33679,7 +33742,7 @@ class MaterialLocalizationPt extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Pesquisa'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Pesquisar na Web'; @override String get selectAllButtonLabel => 'Selecionar tudo'; @@ -33706,7 +33769,7 @@ class MaterialLocalizationPt extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Compartilhar…'; @override String get showAccountsLabel => 'Mostrar contas'; @@ -33769,6 +33832,9 @@ class MaterialLocalizationPtPt extends MaterialLocalizationPt { required super.twoDigitZeroPaddedFormat, }); + @override + String get shareButtonLabel => 'Partilhar…'; + @override String get lookUpButtonLabel => 'Procurar'; @@ -34236,7 +34302,7 @@ class MaterialLocalizationRo extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Licențe'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Privire în sus'; @override String get menuBarMenuLabel => 'Bară de meniu'; @@ -34344,7 +34410,7 @@ class MaterialLocalizationRo extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Căutați'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Căutați pe web'; @override String get selectAllButtonLabel => 'Selectați tot'; @@ -34371,7 +34437,7 @@ class MaterialLocalizationRo extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'Nu există elemente selectate'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Trimiteți…'; @override String get showAccountsLabel => 'Afișați conturile'; @@ -34726,7 +34792,7 @@ class MaterialLocalizationRu extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Лицензии'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Найти'; @override String get menuBarMenuLabel => 'Строка меню'; @@ -34834,7 +34900,7 @@ class MaterialLocalizationRu extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Поиск'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Искать в интернете'; @override String get selectAllButtonLabel => 'Выбрать все'; @@ -34861,7 +34927,7 @@ class MaterialLocalizationRu extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'Строки не выбраны'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Поделиться'; @override String get showAccountsLabel => 'Показать аккаунты'; @@ -35216,7 +35282,7 @@ class MaterialLocalizationSi extends GlobalMaterialLocalizations { String get licensesPageTitle => 'බලපත්‍ර'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'උඩ බලන්න'; @override String get menuBarMenuLabel => 'මෙනු තීරු මෙනුව'; @@ -35324,7 +35390,7 @@ class MaterialLocalizationSi extends GlobalMaterialLocalizations { String get searchFieldLabel => 'සෙවීම'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'වෙබය සොයන්න'; @override String get selectAllButtonLabel => 'සියල්ල තෝරන්න'; @@ -35351,7 +35417,7 @@ class MaterialLocalizationSi extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'බෙදා ගන්න...'; @override String get showAccountsLabel => 'ගිණුම් පෙන්වන්න'; @@ -35706,7 +35772,7 @@ class MaterialLocalizationSk extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Licencie'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Pohľad nahor'; @override String get menuBarMenuLabel => 'Ponuka panela s ponukami'; @@ -35814,7 +35880,7 @@ class MaterialLocalizationSk extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Hľadať'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Hľadať na webe'; @override String get selectAllButtonLabel => 'Vybrať všetko'; @@ -35841,7 +35907,7 @@ class MaterialLocalizationSk extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Zdieľať…'; @override String get showAccountsLabel => 'Zobraziť účty'; @@ -36196,7 +36262,7 @@ class MaterialLocalizationSl extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Licence'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Pogled gor'; @override String get menuBarMenuLabel => 'Meni menijske vrstice'; @@ -36304,7 +36370,7 @@ class MaterialLocalizationSl extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Iskanje'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Iskanje v spletu'; @override String get selectAllButtonLabel => 'Izberi vse'; @@ -36331,7 +36397,7 @@ class MaterialLocalizationSl extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Deli …'; @override String get showAccountsLabel => 'Prikaz računov'; @@ -36686,7 +36752,7 @@ class MaterialLocalizationSq extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Licencat'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Kërko'; @override String get menuBarMenuLabel => 'Menyja e shiritit të menysë'; @@ -36794,7 +36860,7 @@ class MaterialLocalizationSq extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Kërko'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Kërko në ueb'; @override String get selectAllButtonLabel => 'Zgjidh të gjitha'; @@ -36821,7 +36887,7 @@ class MaterialLocalizationSq extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Ndaj...'; @override String get showAccountsLabel => 'Shfaq llogaritë'; @@ -37176,7 +37242,7 @@ class MaterialLocalizationSr extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Лиценце'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Поглед нагоре'; @override String get menuBarMenuLabel => 'Мени трака менија'; @@ -37284,7 +37350,7 @@ class MaterialLocalizationSr extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Претражите'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Претражи веб'; @override String get selectAllButtonLabel => 'Изабери све'; @@ -37311,7 +37377,7 @@ class MaterialLocalizationSr extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Дели…'; @override String get showAccountsLabel => 'Прикажи налоге'; @@ -37546,6 +37612,9 @@ class MaterialLocalizationSrLatn extends MaterialLocalizationSr { @override String get licensesPageTitle => 'Licence'; + @override + String get lookUpButtonLabel => 'Pogled nagore'; + @override String get menuBarMenuLabel => 'Meni traka menija'; @@ -37639,6 +37708,9 @@ class MaterialLocalizationSrLatn extends MaterialLocalizationSr { @override String get searchFieldLabel => 'Pretražite'; + @override + String get searchWebButtonLabel => 'Pretraži veb'; + @override String get selectAllButtonLabel => 'Izaberi sve'; @@ -37654,6 +37726,9 @@ class MaterialLocalizationSrLatn extends MaterialLocalizationSr { @override String get selectedRowCountTitleOther => r'Izabrano je $selectedRowCount stavki'; + @override + String get shareButtonLabel => 'Deli…'; + @override String get showAccountsLabel => 'Prikaži naloge'; @@ -38004,7 +38079,7 @@ class MaterialLocalizationSv extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Licenser'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Titta upp'; @override String get menuBarMenuLabel => 'Menyrad'; @@ -38112,7 +38187,7 @@ class MaterialLocalizationSv extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Sök'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Sök på webben'; @override String get selectAllButtonLabel => 'Markera allt'; @@ -38139,7 +38214,7 @@ class MaterialLocalizationSv extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Dela …'; @override String get showAccountsLabel => 'Visa konton'; @@ -38494,7 +38569,7 @@ class MaterialLocalizationSw extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Leseni'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Tafuta'; @override String get menuBarMenuLabel => 'Menyu ya upau wa menyu'; @@ -38602,7 +38677,7 @@ class MaterialLocalizationSw extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Tafuta'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Tafuta kwenye Wavuti'; @override String get selectAllButtonLabel => 'Chagua vyote'; @@ -38629,7 +38704,7 @@ class MaterialLocalizationSw extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'Hamna kilicho chaguliwa'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Shiriki...'; @override String get showAccountsLabel => 'Onyesha akaunti'; @@ -38984,7 +39059,7 @@ class MaterialLocalizationTa extends GlobalMaterialLocalizations { String get licensesPageTitle => 'உரிமங்கள்'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'தேடு'; @override String get menuBarMenuLabel => 'மெனு பட்டியின் மெனு'; @@ -39092,7 +39167,7 @@ class MaterialLocalizationTa extends GlobalMaterialLocalizations { String get searchFieldLabel => 'தேடல்'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'இணையத்தில் தேடு'; @override String get selectAllButtonLabel => 'அனைத்தையும் தேர்ந்தெடு'; @@ -39119,7 +39194,7 @@ class MaterialLocalizationTa extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => 'எந்த வரிசையும் தேர்ந்தெடுக்கவில்லை'; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'பகிர்...'; @override String get showAccountsLabel => 'கணக்குகளைக் காட்டும்'; @@ -39474,7 +39549,7 @@ class MaterialLocalizationTe extends GlobalMaterialLocalizations { String get licensesPageTitle => 'లైసెన్స్‌లు'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'వెతకండి'; @override String get menuBarMenuLabel => 'మెనూ బార్ మెనూ'; @@ -39582,7 +39657,7 @@ class MaterialLocalizationTe extends GlobalMaterialLocalizations { String get searchFieldLabel => 'వెతకండి'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'వెబ్‌లో సెర్చ్ చేయండి'; @override String get selectAllButtonLabel => 'అన్నింటినీ ఎంచుకోండి'; @@ -39609,7 +39684,7 @@ class MaterialLocalizationTe extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'షేర్ చేయండి...'; @override String get showAccountsLabel => 'ఖాతాలను చూపు'; @@ -39964,7 +40039,7 @@ class MaterialLocalizationTh extends GlobalMaterialLocalizations { String get licensesPageTitle => 'ใบอนุญาต'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'ค้นหา'; @override String get menuBarMenuLabel => 'เมนูในแถบเมนู'; @@ -40072,7 +40147,7 @@ class MaterialLocalizationTh extends GlobalMaterialLocalizations { String get searchFieldLabel => 'ค้นหา'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ค้นหาบนอินเทอร์เน็ต'; @override String get selectAllButtonLabel => 'เลือกทั้งหมด'; @@ -40099,7 +40174,7 @@ class MaterialLocalizationTh extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'แชร์...'; @override String get showAccountsLabel => 'แสดงบัญชี'; @@ -40562,7 +40637,7 @@ class MaterialLocalizationTl extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Maghanap'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Maghanap sa Web'; @override String get selectAllButtonLabel => 'Piliin lahat'; @@ -40589,7 +40664,7 @@ class MaterialLocalizationTl extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Ibahagi...'; @override String get showAccountsLabel => 'Ipakita ang mga account'; @@ -40944,7 +41019,7 @@ class MaterialLocalizationTr extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Lisanslar'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Ara'; @override String get menuBarMenuLabel => 'Menü çubuğu menüsü'; @@ -41052,7 +41127,7 @@ class MaterialLocalizationTr extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Ara'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => "Web'de Ara"; @override String get selectAllButtonLabel => 'Tümünü seç'; @@ -41079,7 +41154,7 @@ class MaterialLocalizationTr extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Paylaş...'; @override String get showAccountsLabel => 'Hesapları göster'; @@ -41434,7 +41509,7 @@ class MaterialLocalizationUk extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Ліцензії'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Шукати'; @override String get menuBarMenuLabel => 'Панель меню'; @@ -41542,7 +41617,7 @@ class MaterialLocalizationUk extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Пошук'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Пошук в Інтернеті'; @override String get selectAllButtonLabel => 'Вибрати всі'; @@ -41569,7 +41644,7 @@ class MaterialLocalizationUk extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Поділитися…'; @override String get showAccountsLabel => 'Показати облікові записи'; @@ -41924,7 +41999,7 @@ class MaterialLocalizationUr extends GlobalMaterialLocalizations { String get licensesPageTitle => 'لائسنسز'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'تفصیل دیکھیں'; @override String get menuBarMenuLabel => 'مینیو بار کا مینیو'; @@ -42032,7 +42107,7 @@ class MaterialLocalizationUr extends GlobalMaterialLocalizations { String get searchFieldLabel => 'تلاش'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'ویب تلاش کریں'; @override String get selectAllButtonLabel => 'سبھی کو منتخب کریں'; @@ -42059,7 +42134,7 @@ class MaterialLocalizationUr extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'اشتراک کریں...'; @override String get showAccountsLabel => 'اکاؤنٹس دکھائیں'; @@ -42522,7 +42597,7 @@ class MaterialLocalizationUz extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Qidirish'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Internetdan qidirish'; @override String get selectAllButtonLabel => 'Hammasi'; @@ -42549,7 +42624,7 @@ class MaterialLocalizationUz extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Ulashish…'; @override String get showAccountsLabel => 'Hisoblarni koʻrsatish'; @@ -42904,7 +42979,7 @@ class MaterialLocalizationVi extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Giấy phép'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Tra cứu'; @override String get menuBarMenuLabel => 'Trình đơn của thanh trình đơn'; @@ -43012,7 +43087,7 @@ class MaterialLocalizationVi extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Tìm kiếm'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Tìm kiếm trên web'; @override String get selectAllButtonLabel => 'Chọn tất cả'; @@ -43039,7 +43114,7 @@ class MaterialLocalizationVi extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Chia sẻ...'; @override String get showAccountsLabel => 'Hiển thị tài khoản'; @@ -43211,7 +43286,7 @@ class MaterialLocalizationZh extends GlobalMaterialLocalizations { String get firstPageTooltip => '第一页'; @override - String get hideAccountsLabel => '隐藏帐号'; + String get hideAccountsLabel => '隐藏账号'; @override String get inputDateModeButtonLabel => '切换到输入模式'; @@ -43394,7 +43469,7 @@ class MaterialLocalizationZh extends GlobalMaterialLocalizations { String get licensesPageTitle => '许可'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => '向上看'; @override String get menuBarMenuLabel => '菜单栏的菜单'; @@ -43502,7 +43577,7 @@ class MaterialLocalizationZh extends GlobalMaterialLocalizations { String get searchFieldLabel => '搜索'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => '在网络上搜索'; @override String get selectAllButtonLabel => '全选'; @@ -43529,10 +43604,10 @@ class MaterialLocalizationZh extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => '分享…'; @override - String get showAccountsLabel => '显示帐号'; + String get showAccountsLabel => '显示账号'; @override String get showMenuTooltip => '显示菜单'; @@ -43911,6 +43986,9 @@ class MaterialLocalizationZhHant extends MaterialLocalizationZh { @override String get searchFieldLabel => '搜尋'; + @override + String get searchWebButtonLabel => '搜尋網頁'; + @override String get selectAllButtonLabel => '全部選取'; @@ -43997,6 +44075,9 @@ class MaterialLocalizationZhHantTw extends MaterialLocalizationZhHant { required super.twoDigitZeroPaddedFormat, }); + @override + String get searchWebButtonLabel => '在網路上搜尋'; + @override String get scanTextButtonLabel => '掃描文字'; @@ -44419,7 +44500,7 @@ class MaterialLocalizationZu extends GlobalMaterialLocalizations { String get licensesPageTitle => 'Amalayisense'; @override - String get lookUpButtonLabel => 'Look Up'; + String get lookUpButtonLabel => 'Bheka Phezulu'; @override String get menuBarMenuLabel => 'Imenyu yebha yemenyu'; @@ -44527,7 +44608,7 @@ class MaterialLocalizationZu extends GlobalMaterialLocalizations { String get searchFieldLabel => 'Sesha'; @override - String get searchWebButtonLabel => 'Search Web'; + String get searchWebButtonLabel => 'Sesha Iwebhu'; @override String get selectAllButtonLabel => 'Khetha konke'; @@ -44554,7 +44635,7 @@ class MaterialLocalizationZu extends GlobalMaterialLocalizations { String? get selectedRowCountTitleZero => null; @override - String get shareButtonLabel => 'Share...'; + String get shareButtonLabel => 'Yabelana...'; @override String get showAccountsLabel => 'Bonisa ama-akhawunti'; diff --git a/packages/flutter_localizations/lib/src/l10n/material_af.arb b/packages/flutter_localizations/lib/src/l10n/material_af.arb index 654ccdf1eacba..f5b3c687e0cbe 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_af.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_af.arb @@ -142,7 +142,7 @@ "expandedHint": "Ingevou", "collapsedHint": "Uitgevou", "menuDismissLabel": "Maak kieslys toe", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Kyk op", + "searchWebButtonLabel": "Deursoek web", + "shareButtonLabel": "Deel …" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_am.arb b/packages/flutter_localizations/lib/src/l10n/material_am.arb index 20158502e0817..51dc86d3044db 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_am.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_am.arb @@ -142,7 +142,7 @@ "expandedHint": "ተሰብስቧል", "collapsedHint": "ተዘርግቷል", "menuDismissLabel": "ምናሌን አሰናብት", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "ይመልከቱ", + "searchWebButtonLabel": "ድርን ፈልግ", + "shareButtonLabel": "አጋራ..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_ar.arb b/packages/flutter_localizations/lib/src/l10n/material_ar.arb index 18ee13a83e302..370681124c44e 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_ar.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_ar.arb @@ -153,7 +153,7 @@ "expandedHint": "مصغَّر", "collapsedHint": "موسَّع", "menuDismissLabel": "إغلاق القائمة", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "النظر إلى أعلى", + "searchWebButtonLabel": "البحث على الويب", + "shareButtonLabel": "مشاركة…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_as.arb b/packages/flutter_localizations/lib/src/l10n/material_as.arb index 79fb39ea71c1f..0873873046f35 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_as.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_as.arb @@ -142,7 +142,7 @@ "expandedHint": "সংকোচন কৰা আছে", "collapsedHint": "বিস্তাৰ কৰা আছে", "menuDismissLabel": "অগ্ৰাহ্য কৰাৰ মেনু", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "ওপৰলৈ চাওক", + "searchWebButtonLabel": "ৱেবত সন্ধান কৰক", + "shareButtonLabel": "শ্বেয়াৰ কৰক…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_az.arb b/packages/flutter_localizations/lib/src/l10n/material_az.arb index cc2a3321445bf..a792a444bf51e 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_az.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_az.arb @@ -142,7 +142,7 @@ "expandedHint": "Yığcamlaşdırıldı", "collapsedHint": "Genişləndirildi", "menuDismissLabel": "Menyunu qapadın", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Axtarın", + "searchWebButtonLabel": "Vebdə axtarın", + "shareButtonLabel": "Paylaşın..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_be.arb b/packages/flutter_localizations/lib/src/l10n/material_be.arb index 2c6dbca5b316c..893e45bcacfc5 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_be.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_be.arb @@ -148,7 +148,7 @@ "expandedHint": "Згорнута", "collapsedHint": "Разгорнута", "menuDismissLabel": "Закрыць меню", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Знайсці", + "searchWebButtonLabel": "Пошук у сетцы", + "shareButtonLabel": "Абагуліць..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_bg.arb b/packages/flutter_localizations/lib/src/l10n/material_bg.arb index ad124c3a09e24..ac4cd5c55e38d 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_bg.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_bg.arb @@ -144,6 +144,6 @@ "collapsedHint": "Разгънато", "menuDismissLabel": "Отхвърляне на менюто", "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Търсене в мрежата", + "shareButtonLabel": "Споделяне..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_bn.arb b/packages/flutter_localizations/lib/src/l10n/material_bn.arb index 77d039992b6a6..66fd3fa0d4fa6 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_bn.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_bn.arb @@ -142,7 +142,7 @@ "expandedHint": "আড়াল করা হয়েছে", "collapsedHint": "বড় করা হয়েছে", "menuDismissLabel": "বাতিল করার মেনু", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "লুক-আপ", + "searchWebButtonLabel": "ওয়েবে সার্চ করুন", + "shareButtonLabel": "শেয়ার করুন..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_bs.arb b/packages/flutter_localizations/lib/src/l10n/material_bs.arb index 424b0e7f9079c..9c2ba601ad3de 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_bs.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_bs.arb @@ -146,7 +146,7 @@ "expandedHint": "Suženo", "collapsedHint": "Prošireno", "menuDismissLabel": "Odbacivanje menija", - "lookUpButtonLabel": "Pogled prema gore", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Pogled nagore", + "searchWebButtonLabel": "Pretraži Web", + "shareButtonLabel": "Dijeli..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_ca.arb b/packages/flutter_localizations/lib/src/l10n/material_ca.arb index 3f2b74212aad9..d4ed502d81e42 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_ca.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_ca.arb @@ -143,7 +143,7 @@ "expandedHint": "S'ha replegat", "collapsedHint": "S'ha desplegat", "menuDismissLabel": "Ignora el menú", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Mira amunt", + "searchWebButtonLabel": "Cerca al web", + "shareButtonLabel": "Comparteix..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_cs.arb b/packages/flutter_localizations/lib/src/l10n/material_cs.arb index dccaa7511212c..e56961b4b8ad7 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_cs.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_cs.arb @@ -149,7 +149,7 @@ "expandedHint": "Sbaleno", "collapsedHint": "Rozbaleno", "menuDismissLabel": "Zavřít nabídku", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Vyhledat", + "searchWebButtonLabel": "Vyhledávat na webu", + "shareButtonLabel": "Sdílet…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_cy.arb b/packages/flutter_localizations/lib/src/l10n/material_cy.arb index 61ce3f86520be..a6c0bdd741fb9 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_cy.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_cy.arb @@ -153,7 +153,7 @@ "collapsedHint": "Wedi'i ehangu", "scanTextButtonLabel": "Sganio testun", "menuDismissLabel": "Diystyru'r ddewislen", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Chwilio", + "searchWebButtonLabel": "Chwilio'r We", + "shareButtonLabel": "Rhannu..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_da.arb b/packages/flutter_localizations/lib/src/l10n/material_da.arb index 582686b1da882..a9d69e6d95857 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_da.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_da.arb @@ -143,7 +143,7 @@ "expandedHint": "Skjult", "collapsedHint": "Udvidet", "menuDismissLabel": "Luk menu", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Slå op", + "searchWebButtonLabel": "Søg på nettet", + "shareButtonLabel": "Del…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_de.arb b/packages/flutter_localizations/lib/src/l10n/material_de.arb index 7739ab93f08f0..7c5f15ff0b171 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_de.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_de.arb @@ -144,7 +144,7 @@ "expandedHint": "Minimiert", "collapsedHint": "Maximiert", "menuDismissLabel": "Menü schließen", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Nachschlagen", + "searchWebButtonLabel": "Im Web suchen", + "shareButtonLabel": "Teilen…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_el.arb b/packages/flutter_localizations/lib/src/l10n/material_el.arb index 48a6551b2ad8b..caa06d23534fb 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_el.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_el.arb @@ -144,6 +144,6 @@ "collapsedHint": "Αναπτύχθηκε", "menuDismissLabel": "Παράβλεψη μενού", "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Αναζήτηση στον ιστό", + "shareButtonLabel": "Κοινοποίηση…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_en_AU.arb b/packages/flutter_localizations/lib/src/l10n/material_en_AU.arb index e9891cde9b804..e220530b9a6ca 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_en_AU.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_en_AU.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "scanTextButtonLabel": "Scan text", "lookUpButtonLabel": "Look up", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/material_en_GB.arb b/packages/flutter_localizations/lib/src/l10n/material_en_GB.arb index 22a307061e77c..f9f5a43dc744e 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_en_GB.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_en_GB.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "scanTextButtonLabel": "Scan text", "lookUpButtonLabel": "Look up", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/material_en_IE.arb b/packages/flutter_localizations/lib/src/l10n/material_en_IE.arb index 22a307061e77c..f9f5a43dc744e 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_en_IE.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_en_IE.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "scanTextButtonLabel": "Scan text", "lookUpButtonLabel": "Look up", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/material_en_IN.arb b/packages/flutter_localizations/lib/src/l10n/material_en_IN.arb index e9891cde9b804..e220530b9a6ca 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_en_IN.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_en_IN.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "scanTextButtonLabel": "Scan text", "lookUpButtonLabel": "Look up", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/material_en_NZ.arb b/packages/flutter_localizations/lib/src/l10n/material_en_NZ.arb index 2fc0ba78f24f1..4f95f027d47ef 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_en_NZ.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_en_NZ.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "scanTextButtonLabel": "Scan text", "lookUpButtonLabel": "Look up", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/material_en_SG.arb b/packages/flutter_localizations/lib/src/l10n/material_en_SG.arb index e9891cde9b804..e220530b9a6ca 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_en_SG.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_en_SG.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "scanTextButtonLabel": "Scan text", "lookUpButtonLabel": "Look up", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/material_en_ZA.arb b/packages/flutter_localizations/lib/src/l10n/material_en_ZA.arb index 22a307061e77c..f9f5a43dc744e 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_en_ZA.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_en_ZA.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Search Web", + "shareButtonLabel": "Share...", "scanTextButtonLabel": "Scan text", "lookUpButtonLabel": "Look up", "menuDismissLabel": "Dismiss menu", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es.arb b/packages/flutter_localizations/lib/src/l10n/material_es.arb index 044c124f1867d..b0b3a04a88303 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es.arb @@ -144,7 +144,7 @@ "expandedHint": "Contraído", "collapsedHint": "Desplegado", "menuDismissLabel": "Cerrar menú", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Buscador visual", + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_419.arb b/packages/flutter_localizations/lib/src/l10n/material_es_419.arb index 12d41aa41ffbb..6e8c8b8088aff 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_419.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_419.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_AR.arb b/packages/flutter_localizations/lib/src/l10n/material_es_AR.arb index 12d41aa41ffbb..6e8c8b8088aff 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_AR.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_AR.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_BO.arb b/packages/flutter_localizations/lib/src/l10n/material_es_BO.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_BO.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_BO.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_CL.arb b/packages/flutter_localizations/lib/src/l10n/material_es_CL.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_CL.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_CL.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_CO.arb b/packages/flutter_localizations/lib/src/l10n/material_es_CO.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_CO.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_CO.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_CR.arb b/packages/flutter_localizations/lib/src/l10n/material_es_CR.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_CR.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_CR.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_DO.arb b/packages/flutter_localizations/lib/src/l10n/material_es_DO.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_DO.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_DO.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_EC.arb b/packages/flutter_localizations/lib/src/l10n/material_es_EC.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_EC.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_EC.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_GT.arb b/packages/flutter_localizations/lib/src/l10n/material_es_GT.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_GT.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_GT.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_HN.arb b/packages/flutter_localizations/lib/src/l10n/material_es_HN.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_HN.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_HN.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_MX.arb b/packages/flutter_localizations/lib/src/l10n/material_es_MX.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_MX.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_MX.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_NI.arb b/packages/flutter_localizations/lib/src/l10n/material_es_NI.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_NI.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_NI.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_PA.arb b/packages/flutter_localizations/lib/src/l10n/material_es_PA.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_PA.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_PA.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_PE.arb b/packages/flutter_localizations/lib/src/l10n/material_es_PE.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_PE.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_PE.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_PR.arb b/packages/flutter_localizations/lib/src/l10n/material_es_PR.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_PR.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_PR.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_PY.arb b/packages/flutter_localizations/lib/src/l10n/material_es_PY.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_PY.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_PY.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_SV.arb b/packages/flutter_localizations/lib/src/l10n/material_es_SV.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_SV.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_SV.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_US.arb b/packages/flutter_localizations/lib/src/l10n/material_es_US.arb index 47144eb6515d5..972872a50a1e6 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_US.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_US.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_UY.arb b/packages/flutter_localizations/lib/src/l10n/material_es_UY.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_UY.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_UY.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_es_VE.arb b/packages/flutter_localizations/lib/src/l10n/material_es_VE.arb index 9e7f8d7fffe25..c3f6d8c45142f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_es_VE.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_es_VE.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Buscar en la Web", + "shareButtonLabel": "Compartir…", "scanTextButtonLabel": "Analizar texto", "lookUpButtonLabel": "Mirar hacia arriba", "menuDismissLabel": "Descartar menú", diff --git a/packages/flutter_localizations/lib/src/l10n/material_et.arb b/packages/flutter_localizations/lib/src/l10n/material_et.arb index 6f207f1d4d3c4..29fe9da03742f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_et.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_et.arb @@ -144,6 +144,6 @@ "collapsedHint": "Laiendatud", "menuDismissLabel": "Sulge menüü", "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Otsi veebist", + "shareButtonLabel": "Jaga …" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_eu.arb b/packages/flutter_localizations/lib/src/l10n/material_eu.arb index 741eacdd0ad4d..02047fd64b0fb 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_eu.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_eu.arb @@ -142,7 +142,7 @@ "expandedHint": "Tolestuta", "collapsedHint": "Zabalduta", "menuDismissLabel": "Baztertu menua", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Bilatu", + "searchWebButtonLabel": "Bilatu sarean", + "shareButtonLabel": "Partekatu..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_fa.arb b/packages/flutter_localizations/lib/src/l10n/material_fa.arb index 35d66dd050c81..ab93807f79f6a 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_fa.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_fa.arb @@ -143,7 +143,7 @@ "expandedHint": "جمع‌شده", "collapsedHint": "ازهم بازشده", "menuDismissLabel": "بستن منو", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "جستجو", + "searchWebButtonLabel": "جستجو در وب", + "shareButtonLabel": "هم‌رسانی…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_fi.arb b/packages/flutter_localizations/lib/src/l10n/material_fi.arb index 283690abdd086..9acbc888076cc 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_fi.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_fi.arb @@ -143,7 +143,7 @@ "expandedHint": "Tiivistetty", "collapsedHint": "Laajennettu", "menuDismissLabel": "Hylkää valikko", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Hae", + "searchWebButtonLabel": "Hae verkosta", + "shareButtonLabel": "Jaa…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_fil.arb b/packages/flutter_localizations/lib/src/l10n/material_fil.arb index 81500d0ee0cb3..3c94fb44e4b62 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_fil.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_fil.arb @@ -144,6 +144,6 @@ "collapsedHint": "Naka-expand", "menuDismissLabel": "I-dismiss ang menu", "lookUpButtonLabel": "Tumingin sa Itaas", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Maghanap sa Web", + "shareButtonLabel": "Ibahagi..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_fr.arb b/packages/flutter_localizations/lib/src/l10n/material_fr.arb index 73ca135a2b17f..0791be843c8cd 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_fr.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_fr.arb @@ -144,7 +144,7 @@ "expandedHint": "Réduit", "collapsedHint": "Développé", "menuDismissLabel": "Fermer le menu", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Recherche visuelle", + "searchWebButtonLabel": "Rechercher sur le Web", + "shareButtonLabel": "Partager…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_fr_CA.arb b/packages/flutter_localizations/lib/src/l10n/material_fr_CA.arb index 0764fcca20a9a..0ca0bbc278743 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_fr_CA.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_fr_CA.arb @@ -1,4 +1,7 @@ { + "lookUpButtonLabel": "Regarder en haut", + "searchWebButtonLabel": "Rechercher sur le Web", + "shareButtonLabel": "Partager…", "scanTextButtonLabel": "Balayer un texte", "menuDismissLabel": "Ignorer le menu", "expansionTileExpandedHint": "toucher deux fois pour réduire", diff --git a/packages/flutter_localizations/lib/src/l10n/material_gl.arb b/packages/flutter_localizations/lib/src/l10n/material_gl.arb index c4989e91aa616..427dfef7fc132 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_gl.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_gl.arb @@ -145,6 +145,6 @@ "collapsedHint": "Despregado", "menuDismissLabel": "Pechar menú", "lookUpButtonLabel": "Mirar cara arriba", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Buscar na Web", + "shareButtonLabel": "Compartir…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_gsw.arb b/packages/flutter_localizations/lib/src/l10n/material_gsw.arb index 6e459e9d0c27c..7400fe259f109 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_gsw.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_gsw.arb @@ -143,7 +143,7 @@ "expandedHint": "Minimiert", "collapsedHint": "Maximiert", "menuDismissLabel": "Menü schließen", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Nachschlagen", + "searchWebButtonLabel": "Im Web suchen", + "shareButtonLabel": "Teilen…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_gu.arb b/packages/flutter_localizations/lib/src/l10n/material_gu.arb index ce1c833d9babb..7948f1413b8c2 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_gu.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_gu.arb @@ -142,7 +142,7 @@ "expandedHint": "નાની કરી", "collapsedHint": "મોટી કરી", "menuDismissLabel": "મેનૂ છોડી દો", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "શોધો", + "searchWebButtonLabel": "વેબ પર શોધો", + "shareButtonLabel": "શેર કરો…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_he.arb b/packages/flutter_localizations/lib/src/l10n/material_he.arb index 7e5ed5c95455b..9af3753a4008f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_he.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_he.arb @@ -149,7 +149,7 @@ "expandedHint": "מכווץ", "collapsedHint": "מורחב", "menuDismissLabel": "סגירת התפריט", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "חיפוש", + "searchWebButtonLabel": "חיפוש באינטרנט", + "shareButtonLabel": "שיתוף…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_hi.arb b/packages/flutter_localizations/lib/src/l10n/material_hi.arb index 38ac3fd0bdb9b..160403a9a728d 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_hi.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_hi.arb @@ -143,7 +143,7 @@ "expandedHint": "छोटा किया गया", "collapsedHint": "बड़ा किया गया", "menuDismissLabel": "मेन्यू खारिज करें", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "लुक अप बटन", + "searchWebButtonLabel": "वेब पर खोजें", + "shareButtonLabel": "शेयर करें…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_hr.arb b/packages/flutter_localizations/lib/src/l10n/material_hr.arb index 59cf13db5ece5..0f09c1ff862b3 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_hr.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_hr.arb @@ -147,6 +147,6 @@ "collapsedHint": "Prošireno", "menuDismissLabel": "Odbacivanje izbornika", "lookUpButtonLabel": "Pogled prema gore", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Pretraži web", + "shareButtonLabel": "Dijeli..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_hu.arb b/packages/flutter_localizations/lib/src/l10n/material_hu.arb index df2ba6d9ccda8..0282eeb96cc0e 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_hu.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_hu.arb @@ -144,6 +144,6 @@ "collapsedHint": "Kibontva", "menuDismissLabel": "Menü bezárása", "lookUpButtonLabel": "Felfelé nézés", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Keresés az interneten", + "shareButtonLabel": "Megosztás…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_hy.arb b/packages/flutter_localizations/lib/src/l10n/material_hy.arb index 8a005fda07db1..8ed53ffd3241d 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_hy.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_hy.arb @@ -148,7 +148,7 @@ "expandedHint": "Ծալված է", "collapsedHint": "Ծավալված է", "menuDismissLabel": "Փակել ընտրացանկը", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Փնտրել", + "searchWebButtonLabel": "Որոնել համացանցում", + "shareButtonLabel": "Կիսվել..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_id.arb b/packages/flutter_localizations/lib/src/l10n/material_id.arb index c43af93ec3991..f317fc7ac73e2 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_id.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_id.arb @@ -143,7 +143,7 @@ "expandedHint": "Diciutkan", "collapsedHint": "Diluaskan", "menuDismissLabel": "Tutup menu", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Cari", + "searchWebButtonLabel": "Telusuri di Web", + "shareButtonLabel": "Bagikan..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_is.arb b/packages/flutter_localizations/lib/src/l10n/material_is.arb index 8dbc6518dd4b3..60d5419b73324 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_is.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_is.arb @@ -143,6 +143,6 @@ "collapsedHint": "Stækkað", "menuDismissLabel": "Loka valmynd", "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Leita á vefnum", + "shareButtonLabel": "Deila..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_it.arb b/packages/flutter_localizations/lib/src/l10n/material_it.arb index f8094612375f7..93ec457dfd4d7 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_it.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_it.arb @@ -144,6 +144,6 @@ "collapsedHint": "Espanso", "menuDismissLabel": "Ignora menu", "lookUpButtonLabel": "Cerca", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Cerca sul web", + "shareButtonLabel": "Condividi…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_ja.arb b/packages/flutter_localizations/lib/src/l10n/material_ja.arb index 02700410405be..61d84a0d781b6 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_ja.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_ja.arb @@ -28,7 +28,7 @@ "scanTextButtonLabel": "テキストをスキャン", "okButtonLabel": "OK", "pasteButtonLabel": "貼り付け", - "selectAllButtonLabel": "すべて選択", + "selectAllButtonLabel": "すべてを選択", "viewLicensesButtonLabel": "ライセンスを表示", "anteMeridiemAbbreviation": "AM", "postMeridiemAbbreviation": "PM", @@ -144,6 +144,6 @@ "collapsedHint": "開きました", "menuDismissLabel": "メニューを閉じる", "lookUpButtonLabel": "調べる", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "ウェブを検索", + "shareButtonLabel": "共有..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_ka.arb b/packages/flutter_localizations/lib/src/l10n/material_ka.arb index 1fc8909e336c0..dba1fd353a118 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_ka.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_ka.arb @@ -142,7 +142,7 @@ "expandedHint": "ჩაკეცილია", "collapsedHint": "გაფართოებულია", "menuDismissLabel": "მენიუს უარყოფა", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "აიხედეთ ზემოთ", + "searchWebButtonLabel": "ვებში ძიება", + "shareButtonLabel": "გაზიარება..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_kk.arb b/packages/flutter_localizations/lib/src/l10n/material_kk.arb index efd070ee1b8d1..8e395334ff9b7 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_kk.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_kk.arb @@ -144,7 +144,7 @@ "expandedHint": "Жиылды", "collapsedHint": "Жайылды", "menuDismissLabel": "Мәзірді жабу", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Іздеу", + "searchWebButtonLabel": "Интернеттен іздеу", + "shareButtonLabel": "Бөлісу…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_km.arb b/packages/flutter_localizations/lib/src/l10n/material_km.arb index c14c56ae2c1cf..2d9ad4d97a61e 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_km.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_km.arb @@ -144,6 +144,6 @@ "collapsedHint": "បាន​ពង្រីក", "menuDismissLabel": "ច្រានចោល​ម៉ឺនុយ", "lookUpButtonLabel": "រកមើល", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "ស្វែងរក​លើបណ្ដាញ", + "shareButtonLabel": "ចែករំលែក..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_kn.arb b/packages/flutter_localizations/lib/src/l10n/material_kn.arb index 21cef3bf69d8f..8d56313e2aeee 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_kn.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_kn.arb @@ -142,7 +142,7 @@ "expandedHint": "\u0c95\u0cc1\u0c97\u0ccd\u0c97\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cbf\u0ca6\u0cc6", "collapsedHint": "\u0cb5\u0cbf\u0cb8\u0ccd\u0ca4\u0cb0\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cbf\u0ca6\u0cc6", "menuDismissLabel": "\u0cae\u0cc6\u0ca8\u0cc1\u0cb5\u0ca8\u0ccd\u0ca8\u0cc1\u0020\u0cb5\u0c9c\u0cbe\u0c97\u0cc6\u0cc2\u0cb3\u0cbf\u0cb8\u0cbf", - "lookUpButtonLabel": "\u004c\u006f\u006f\u006b\u0020\u0055\u0070", - "searchWebButtonLabel": "\u0053\u0065\u0061\u0072\u0063\u0068\u0020\u0057\u0065\u0062", - "shareButtonLabel": "\u0053\u0068\u0061\u0072\u0065\u002e\u002e\u002e" + "lookUpButtonLabel": "\u0cae\u0cc7\u0cb2\u0cc6\u0020\u0ca8\u0ccb\u0ca1\u0cbf", + "searchWebButtonLabel": "\u0cb5\u0cc6\u0cac\u0ccd\u200c\u0ca8\u0cb2\u0ccd\u0cb2\u0cbf\u0020\u0cb9\u0cc1\u0ca1\u0cc1\u0c95\u0cbf", + "shareButtonLabel": "\u0cb9\u0c82\u0c9a\u0cbf\u0c95\u0cca\u0cb3\u0ccd\u0cb3\u0cbf\u002e\u002e\u002e" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_ko.arb b/packages/flutter_localizations/lib/src/l10n/material_ko.arb index fa2856b05255b..038c6617cf2a1 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_ko.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_ko.arb @@ -143,7 +143,7 @@ "expandedHint": "접힘", "collapsedHint": "펼침", "menuDismissLabel": "메뉴 닫기", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "찾기", + "searchWebButtonLabel": "웹 검색", + "shareButtonLabel": "공유..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_ky.arb b/packages/flutter_localizations/lib/src/l10n/material_ky.arb index d924c49546930..337edda003ceb 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_ky.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_ky.arb @@ -142,7 +142,7 @@ "expandedHint": "Жыйыштырылды", "collapsedHint": "Жайылып көрсөтүлдү", "menuDismissLabel": "Менюну жабуу", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Издөө", + "searchWebButtonLabel": "Интернеттен издөө", + "shareButtonLabel": "Бөлүшүү…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_lo.arb b/packages/flutter_localizations/lib/src/l10n/material_lo.arb index 69aefa7a22f7c..e7eaecbdbca1a 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_lo.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_lo.arb @@ -142,7 +142,7 @@ "expandedHint": "ຫຍໍ້ລົງແລ້ວ", "collapsedHint": "ຂະຫຍາຍແລ້ວ", "menuDismissLabel": "ປິດເມນູ", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "ຊອກຫາຂໍ້ມູນ", + "searchWebButtonLabel": "ຊອກຫາຢູ່ອິນເຕີເນັດ", + "shareButtonLabel": "ແບ່ງປັນ..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_lt.arb b/packages/flutter_localizations/lib/src/l10n/material_lt.arb index 79138cabaf381..5ff686098854c 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_lt.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_lt.arb @@ -149,7 +149,7 @@ "expandedHint": "Sutraukta", "collapsedHint": "Išskleista", "menuDismissLabel": "Atsisakyti meniu", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Ieškoti", + "searchWebButtonLabel": "Ieškoti žiniatinklyje", + "shareButtonLabel": "Bendrinti..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_lv.arb b/packages/flutter_localizations/lib/src/l10n/material_lv.arb index 32c496d9a9564..352d62ab70120 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_lv.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_lv.arb @@ -144,7 +144,7 @@ "expandedHint": "Sakļauts", "collapsedHint": "Izvērsts", "menuDismissLabel": "Nerādīt izvēlni", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Meklēt", + "searchWebButtonLabel": "Meklēt tīmeklī", + "shareButtonLabel": "Kopīgot…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_mk.arb b/packages/flutter_localizations/lib/src/l10n/material_mk.arb index 6b43ceb0ac867..edc6e79bed5c7 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_mk.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_mk.arb @@ -142,7 +142,7 @@ "expandedHint": "Собрано", "collapsedHint": "Проширено", "menuDismissLabel": "Отфрлете го менито", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Погледнете нагоре", + "searchWebButtonLabel": "Пребарајте на интернет", + "shareButtonLabel": "Споделете..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_ml.arb b/packages/flutter_localizations/lib/src/l10n/material_ml.arb index 2a6737a51dad7..3b9d6114ed28e 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_ml.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_ml.arb @@ -143,6 +143,6 @@ "collapsedHint": "വികസിപ്പിച്ചു", "menuDismissLabel": "മെനു ഡിസ്മിസ് ചെയ്യുക", "lookUpButtonLabel": "മുകളിലേക്ക് നോക്കുക", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "വെബിൽ തിരയുക", + "shareButtonLabel": "പങ്കിടുക..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_mn.arb b/packages/flutter_localizations/lib/src/l10n/material_mn.arb index 20f54fd252f9b..939860c688411 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_mn.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_mn.arb @@ -144,7 +144,7 @@ "expandedHint": "Хураасан", "collapsedHint": "Дэлгэсэн", "menuDismissLabel": "Цэсийг хаах", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Дээшээ харах", + "searchWebButtonLabel": "Вебээс хайх", + "shareButtonLabel": "Хуваалцах..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_mr.arb b/packages/flutter_localizations/lib/src/l10n/material_mr.arb index 0889a9b10e709..6ab11d624dd52 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_mr.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_mr.arb @@ -144,7 +144,7 @@ "expandedHint": "कोलॅप्स केले", "collapsedHint": "विस्तार केले", "menuDismissLabel": "मेनू डिसमिस करा", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "शोध घ्या", + "searchWebButtonLabel": "वेबवर शोधा", + "shareButtonLabel": "शेअर करा..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_ms.arb b/packages/flutter_localizations/lib/src/l10n/material_ms.arb index 352736c017803..75c52f2a915c4 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_ms.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_ms.arb @@ -145,6 +145,6 @@ "collapsedHint": "Dikembangkan", "menuDismissLabel": "Ketepikan menu", "lookUpButtonLabel": "Lihat ke Atas", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Buat carian pada Web", + "shareButtonLabel": "Kongsi..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_my.arb b/packages/flutter_localizations/lib/src/l10n/material_my.arb index bdb51efcb5ec2..0e17510c78b5e 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_my.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_my.arb @@ -142,7 +142,7 @@ "expandedHint": "ခေါက်ထားသည်", "collapsedHint": "ဖြန့်ထားသည်", "menuDismissLabel": "မီနူးကိုပယ်ပါ", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "အပေါ်ကြည့်ရန်", + "searchWebButtonLabel": "ဝဘ်တွင်ရှာရန်", + "shareButtonLabel": "မျှဝေရန်..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_nb.arb b/packages/flutter_localizations/lib/src/l10n/material_nb.arb index 51a9204053277..9afb6409bafc5 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_nb.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_nb.arb @@ -141,7 +141,7 @@ "expandedHint": "Skjules", "collapsedHint": "Vises", "menuDismissLabel": "Lukk menyen", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Slå opp", + "searchWebButtonLabel": "Søk på nettet", + "shareButtonLabel": "Del…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_ne.arb b/packages/flutter_localizations/lib/src/l10n/material_ne.arb index 682ae42d45097..7360be5ba7231 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_ne.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_ne.arb @@ -142,7 +142,7 @@ "expandedHint": "कोल्याप्स गरियो", "collapsedHint": "एक्स्पान्ड गरियो", "menuDismissLabel": "मेनु खारेज गर्नुहोस्", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "माथितिर हेर्नुहोस्", + "searchWebButtonLabel": "वेबमा खोज्नुहोस्", + "shareButtonLabel": "सेयर गर्नुहोस्..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_nl.arb b/packages/flutter_localizations/lib/src/l10n/material_nl.arb index ed6fa8d09939b..620ba9eb9d262 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_nl.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_nl.arb @@ -143,7 +143,7 @@ "expandedHint": "Samengevouwen", "collapsedHint": "Uitgevouwen", "menuDismissLabel": "Menu sluiten", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Opzoeken", + "searchWebButtonLabel": "Op internet zoeken", + "shareButtonLabel": "Delen..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_no.arb b/packages/flutter_localizations/lib/src/l10n/material_no.arb index 51a9204053277..9afb6409bafc5 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_no.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_no.arb @@ -141,7 +141,7 @@ "expandedHint": "Skjules", "collapsedHint": "Vises", "menuDismissLabel": "Lukk menyen", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Slå opp", + "searchWebButtonLabel": "Søk på nettet", + "shareButtonLabel": "Del…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_or.arb b/packages/flutter_localizations/lib/src/l10n/material_or.arb index f912d335d0cad..ea87a5549a161 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_or.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_or.arb @@ -142,7 +142,7 @@ "expandedHint": "ସଙ୍କୁଚିତ କରାଯାଇଛି", "collapsedHint": "ବିସ୍ତାର କରାଯାଇଛି", "menuDismissLabel": "ମେନୁ ଖାରଜ କରନ୍ତୁ", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "ଉପରକୁ ଦେଖନ୍ତୁ", + "searchWebButtonLabel": "ୱେବ ସର୍ଚ୍ଚ କରନ୍ତୁ", + "shareButtonLabel": "ସେୟାର୍ କରନ୍ତୁ..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_pa.arb b/packages/flutter_localizations/lib/src/l10n/material_pa.arb index 3fef6da95ffd8..9dcd535a815c4 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_pa.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_pa.arb @@ -142,7 +142,7 @@ "expandedHint": "ਸਮੇਟਿਆ ਗਿਆ", "collapsedHint": "ਵਿਸਤਾਰ ਕੀਤਾ ਗਿਆ", "menuDismissLabel": "ਮੀਨੂ ਖਾਰਜ ਕਰੋ", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "ਖੋਜੋ", + "searchWebButtonLabel": "ਵੈੱਬ 'ਤੇ ਖੋਜੋ", + "shareButtonLabel": "ਸਾਂਝਾ ਕਰੋ..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_pl.arb b/packages/flutter_localizations/lib/src/l10n/material_pl.arb index a7a4fe5d09997..abf6ecbf7510c 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_pl.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_pl.arb @@ -150,6 +150,6 @@ "collapsedHint": "Rozwinięto", "menuDismissLabel": "Zamknij menu", "lookUpButtonLabel": "Sprawdź", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Szukaj w internecie", + "shareButtonLabel": "Udostępnij…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_pt.arb b/packages/flutter_localizations/lib/src/l10n/material_pt.arb index daf092cf82109..dd0ca89e09b3c 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_pt.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_pt.arb @@ -146,6 +146,6 @@ "collapsedHint": "Aberto.", "menuDismissLabel": "Dispensar menu", "lookUpButtonLabel": "Pesquisar", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Pesquisar na Web", + "shareButtonLabel": "Compartilhar…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_pt_PT.arb b/packages/flutter_localizations/lib/src/l10n/material_pt_PT.arb index a7aa74964fe41..53897157dbf2f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_pt_PT.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_pt_PT.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "Pesquisar na Web", + "shareButtonLabel": "Partilhar…", "scanTextButtonLabel": "Digitalizar texto", "lookUpButtonLabel": "Procurar", "menuDismissLabel": "Ignorar menu", diff --git a/packages/flutter_localizations/lib/src/l10n/material_ro.arb b/packages/flutter_localizations/lib/src/l10n/material_ro.arb index d85a49ff1fdc2..ea4ed0a5de02f 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_ro.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_ro.arb @@ -147,7 +147,7 @@ "expandedHint": "Restrâns", "collapsedHint": "Extins", "menuDismissLabel": "Respingeți meniul", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Privire în sus", + "searchWebButtonLabel": "Căutați pe web", + "shareButtonLabel": "Trimiteți…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_ru.arb b/packages/flutter_localizations/lib/src/l10n/material_ru.arb index a73207d20f4c7..2e9a8a1703953 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_ru.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_ru.arb @@ -150,7 +150,7 @@ "expandedHint": "Свернуто", "collapsedHint": "Развернуто", "menuDismissLabel": "Закрыть меню", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Найти", + "searchWebButtonLabel": "Искать в интернете", + "shareButtonLabel": "Поделиться" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_si.arb b/packages/flutter_localizations/lib/src/l10n/material_si.arb index 4d236f2a8c8a0..853e88f868cec 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_si.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_si.arb @@ -142,7 +142,7 @@ "expandedHint": "හකුළන ලදි", "collapsedHint": "දිග හරින ලදි", "menuDismissLabel": "මෙනුව අස් කරන්න", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "උඩ බලන්න", + "searchWebButtonLabel": "වෙබය සොයන්න", + "shareButtonLabel": "බෙදා ගන්න..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_sk.arb b/packages/flutter_localizations/lib/src/l10n/material_sk.arb index 5b2792a96a22b..924e8bfd50af9 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_sk.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_sk.arb @@ -149,7 +149,7 @@ "expandedHint": "Zbalené", "collapsedHint": "Rozbalené", "menuDismissLabel": "Zavrieť ponuku", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Pohľad nahor", + "searchWebButtonLabel": "Hľadať na webe", + "shareButtonLabel": "Zdieľať…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_sl.arb b/packages/flutter_localizations/lib/src/l10n/material_sl.arb index a850fcb0e73f4..7b4da9d4b1e19 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_sl.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_sl.arb @@ -149,7 +149,7 @@ "expandedHint": "Strnjeno", "collapsedHint": "Razširjeno", "menuDismissLabel": "Opusti meni", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Pogled gor", + "searchWebButtonLabel": "Iskanje v spletu", + "shareButtonLabel": "Deli …" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_sq.arb b/packages/flutter_localizations/lib/src/l10n/material_sq.arb index 82e7bf36597cb..edd65ca19b37b 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_sq.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_sq.arb @@ -142,7 +142,7 @@ "expandedHint": "U palos", "collapsedHint": "U zgjerua", "menuDismissLabel": "Hiqe menynë", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Kërko", + "searchWebButtonLabel": "Kërko në ueb", + "shareButtonLabel": "Ndaj..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_sr.arb b/packages/flutter_localizations/lib/src/l10n/material_sr.arb index b1b745fb08273..b773d20e59501 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_sr.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_sr.arb @@ -146,7 +146,7 @@ "expandedHint": "Скупљено је", "collapsedHint": "Проширено је", "menuDismissLabel": "Одбаците мени", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Поглед нагоре", + "searchWebButtonLabel": "Претражи веб", + "shareButtonLabel": "Дели…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_sr_Latn.arb b/packages/flutter_localizations/lib/src/l10n/material_sr_Latn.arb index d320ce96f4d9e..423743cfbf2fc 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_sr_Latn.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_sr_Latn.arb @@ -1,4 +1,7 @@ { + "lookUpButtonLabel": "Pogled nagore", + "searchWebButtonLabel": "Pretraži veb", + "shareButtonLabel": "Deli…", "scanTextButtonLabel": "Skeniraj tekst", "menuDismissLabel": "Odbacite meni", "expansionTileExpandedHint": "dvaput dodirnite da biste skupili", diff --git a/packages/flutter_localizations/lib/src/l10n/material_sv.arb b/packages/flutter_localizations/lib/src/l10n/material_sv.arb index 6c3925b1cd261..dec93ca21adb1 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_sv.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_sv.arb @@ -143,7 +143,7 @@ "expandedHint": "Komprimerades", "collapsedHint": "Utökades", "menuDismissLabel": "Stäng menyn", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Titta upp", + "searchWebButtonLabel": "Sök på webben", + "shareButtonLabel": "Dela …" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_sw.arb b/packages/flutter_localizations/lib/src/l10n/material_sw.arb index 8d42d166ea43a..3482d2a8283f1 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_sw.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_sw.arb @@ -144,7 +144,7 @@ "expandedHint": "Imekunjwa", "collapsedHint": "Imepanuliwa", "menuDismissLabel": "Ondoa menyu", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Tafuta", + "searchWebButtonLabel": "Tafuta kwenye Wavuti", + "shareButtonLabel": "Shiriki..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_ta.arb b/packages/flutter_localizations/lib/src/l10n/material_ta.arb index 6dbde632081c6..28acf1bbd8046 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_ta.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_ta.arb @@ -144,7 +144,7 @@ "expandedHint": "சுருக்கப்பட்டது", "collapsedHint": "விரிவாக்கப்பட்டது", "menuDismissLabel": "மெனுவை மூடும்", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "தேடு", + "searchWebButtonLabel": "இணையத்தில் தேடு", + "shareButtonLabel": "பகிர்..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_te.arb b/packages/flutter_localizations/lib/src/l10n/material_te.arb index bc1abeef65607..4137abd0d4b61 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_te.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_te.arb @@ -142,7 +142,7 @@ "expandedHint": "కుదించబడింది", "collapsedHint": "విస్తరించబడింది", "menuDismissLabel": "మెనూను తీసివేయండి", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "వెతకండి", + "searchWebButtonLabel": "వెబ్‌లో సెర్చ్ చేయండి", + "shareButtonLabel": "షేర్ చేయండి..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_th.arb b/packages/flutter_localizations/lib/src/l10n/material_th.arb index e12ffad42c386..beff70e171bfa 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_th.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_th.arb @@ -143,7 +143,7 @@ "expandedHint": "ยุบ", "collapsedHint": "ขยาย", "menuDismissLabel": "ปิดเมนู", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "ค้นหา", + "searchWebButtonLabel": "ค้นหาบนอินเทอร์เน็ต", + "shareButtonLabel": "แชร์..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_tl.arb b/packages/flutter_localizations/lib/src/l10n/material_tl.arb index 81500d0ee0cb3..3c94fb44e4b62 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_tl.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_tl.arb @@ -144,6 +144,6 @@ "collapsedHint": "Naka-expand", "menuDismissLabel": "I-dismiss ang menu", "lookUpButtonLabel": "Tumingin sa Itaas", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Maghanap sa Web", + "shareButtonLabel": "Ibahagi..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_tr.arb b/packages/flutter_localizations/lib/src/l10n/material_tr.arb index bfcbc7458b51c..28f1dd6eee738 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_tr.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_tr.arb @@ -143,7 +143,7 @@ "expandedHint": "Daraltıldı", "collapsedHint": "Genişletildi", "menuDismissLabel": "Menüyü kapat", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Ara", + "searchWebButtonLabel": "Web'de Ara", + "shareButtonLabel": "Paylaş..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_uk.arb b/packages/flutter_localizations/lib/src/l10n/material_uk.arb index 40f9098644dde..d230eadee1d7d 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_uk.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_uk.arb @@ -149,7 +149,7 @@ "expandedHint": "Згорнуто", "collapsedHint": "Розгорнуто", "menuDismissLabel": "Закрити меню", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Шукати", + "searchWebButtonLabel": "Пошук в Інтернеті", + "shareButtonLabel": "Поділитися…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_ur.arb b/packages/flutter_localizations/lib/src/l10n/material_ur.arb index cb6c453d4fba3..5562efe460a5a 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_ur.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_ur.arb @@ -143,7 +143,7 @@ "expandedHint": "سکڑا ہوا", "collapsedHint": "پھیلا ہوا", "menuDismissLabel": "مینو برخاست کریں", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "تفصیل دیکھیں", + "searchWebButtonLabel": "ویب تلاش کریں", + "shareButtonLabel": "اشتراک کریں..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_uz.arb b/packages/flutter_localizations/lib/src/l10n/material_uz.arb index 842624888b050..4c29e5b651b94 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_uz.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_uz.arb @@ -143,6 +143,6 @@ "collapsedHint": "Yoyilgan", "menuDismissLabel": "Menyuni yopish", "lookUpButtonLabel": "Tepaga qarang", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "searchWebButtonLabel": "Internetdan qidirish", + "shareButtonLabel": "Ulashish…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_vi.arb b/packages/flutter_localizations/lib/src/l10n/material_vi.arb index 32b1cd43aa2d1..43a7c192f7ec1 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_vi.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_vi.arb @@ -143,7 +143,7 @@ "expandedHint": "Đã thu gọn", "collapsedHint": "Đã mở rộng", "menuDismissLabel": "Đóng trình đơn", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Tra cứu", + "searchWebButtonLabel": "Tìm kiếm trên web", + "shareButtonLabel": "Chia sẻ..." } diff --git a/packages/flutter_localizations/lib/src/l10n/material_zh.arb b/packages/flutter_localizations/lib/src/l10n/material_zh.arb index 0d65ab605fb89..9a7ac0d948197 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_zh.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_zh.arb @@ -35,8 +35,8 @@ "timePickerHourModeAnnouncement": "选择小时", "timePickerMinuteModeAnnouncement": "选择分钟", "signedInLabel": "已登录", - "hideAccountsLabel": "隐藏帐号", - "showAccountsLabel": "显示帐号", + "hideAccountsLabel": "隐藏账号", + "showAccountsLabel": "显示账号", "modalBarrierDismissLabel": "关闭", "drawerLabel": "导航菜单", "popupMenuLabel": "弹出菜单", @@ -143,7 +143,7 @@ "expandedHint": "已收起", "collapsedHint": "已展开", "menuDismissLabel": "关闭菜单", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "向上看", + "searchWebButtonLabel": "在网络上搜索", + "shareButtonLabel": "分享…" } diff --git a/packages/flutter_localizations/lib/src/l10n/material_zh_HK.arb b/packages/flutter_localizations/lib/src/l10n/material_zh_HK.arb index efadc607395fe..55baa2a4110f2 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_zh_HK.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_zh_HK.arb @@ -1,4 +1,6 @@ { + "searchWebButtonLabel": "搜尋網頁", + "shareButtonLabel": "分享…", "scanTextButtonLabel": "掃瞄文字", "lookUpButtonLabel": "查詢", "menuDismissLabel": "閂選單", diff --git a/packages/flutter_localizations/lib/src/l10n/material_zh_TW.arb b/packages/flutter_localizations/lib/src/l10n/material_zh_TW.arb index 33564f3ad11b6..ca63fef879212 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_zh_TW.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_zh_TW.arb @@ -1,4 +1,7 @@ { + "lookUpButtonLabel": "查詢", + "searchWebButtonLabel": "在網路上搜尋", + "shareButtonLabel": "分享…", "scanTextButtonLabel": "掃描文字", "menuDismissLabel": "關閉選單", "expansionTileExpandedHint": "輕觸兩下即可收合", diff --git a/packages/flutter_localizations/lib/src/l10n/material_zu.arb b/packages/flutter_localizations/lib/src/l10n/material_zu.arb index 8cf22c29b915e..4b570d0347d7a 100644 --- a/packages/flutter_localizations/lib/src/l10n/material_zu.arb +++ b/packages/flutter_localizations/lib/src/l10n/material_zu.arb @@ -142,7 +142,7 @@ "expandedHint": "Kugoqiwe", "collapsedHint": "Kunwetshiwe", "menuDismissLabel": "Chitha imenyu", - "lookUpButtonLabel": "Look Up", - "searchWebButtonLabel": "Search Web", - "shareButtonLabel": "Share..." + "lookUpButtonLabel": "Bheka Phezulu", + "searchWebButtonLabel": "Sesha Iwebhu", + "shareButtonLabel": "Yabelana..." } diff --git a/packages/flutter_localizations/pubspec.yaml b/packages/flutter_localizations/pubspec.yaml index 50fb8f06bbc48..c2696da75a5f0 100644 --- a/packages/flutter_localizations/pubspec.yaml +++ b/packages/flutter_localizations/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -34,4 +34,4 @@ dev_dependencies: term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 35a3 +# PUBSPEC CHECKSUM: 40a4 diff --git a/packages/flutter_localizations/test/cupertino/translations_test.dart b/packages/flutter_localizations/test/cupertino/translations_test.dart index a827e0d498f6e..4599634ee6cce 100644 --- a/packages/flutter_localizations/test/cupertino/translations_test.dart +++ b/packages/flutter_localizations/test/cupertino/translations_test.dart @@ -125,7 +125,7 @@ void main() { expect(localizations.pasteButtonLabel, 'Coller'); expect(localizations.datePickerDateOrder, DatePickerDateOrder.dmy); expect(localizations.timerPickerSecondLabel(20), 's'); - expect(localizations.selectAllButtonLabel, 'Tout sélect.'); + expect(localizations.selectAllButtonLabel, 'Tout sélectionner'); expect(localizations.timerPickerMinute(10), '10'); }); diff --git a/packages/flutter_test/pubspec.yaml b/packages/flutter_test/pubspec.yaml index f71a48991d1cd..118b31253f11a 100644 --- a/packages/flutter_test/pubspec.yaml +++ b/packages/flutter_test/pubspec.yaml @@ -40,12 +40,12 @@ dependencies: stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: file: 6.1.4 # Used to detect memory leaks. - leak_tracker_flutter_testing: 1.0.5 + leak_tracker_flutter_testing: 1.0.6 _fe_analyzer_shared: 64.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" analyzer: 6.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -60,7 +60,7 @@ dev_dependencies: intl: 0.18.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - leak_tracker: 9.0.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + leak_tracker: 9.0.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" leak_tracker_testing: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -83,4 +83,4 @@ dev_dependencies: webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: aa8d +# PUBSPEC CHECKSUM: 2e90 diff --git a/packages/flutter_tools/lib/src/base/io.dart b/packages/flutter_tools/lib/src/base/io.dart index 2a6352737b1fa..83473499a9125 100644 --- a/packages/flutter_tools/lib/src/base/io.dart +++ b/packages/flutter_tools/lib/src/base/io.dart @@ -191,15 +191,27 @@ class ProcessSignal { /// /// Returns true if the signal was delivered, false otherwise. /// - /// On Windows, this can only be used with [ProcessSignal.sigterm], which - /// terminates the process. + /// On Windows, this can only be used with [sigterm], which terminates the + /// process. /// - /// This is implemented by sending the signal using [Process.killPid]. + /// This is implemented by sending the signal using [io.Process.killPid] and + /// therefore cannot be faked in tests. To fake sending signals in tests, use + /// [kill] instead. bool send(int pid) { assert(!_platform.isWindows || this == ProcessSignal.sigterm); return io.Process.killPid(pid, _delegate); } + /// A more testable variant of [send]. + /// + /// Sends this signal to the given `process` by invoking [io.Process.kill]. + /// + /// In tests this method can be faked by passing a fake implementation of the + /// [io.Process] interface. + bool kill(io.Process process) { + return process.kill(_delegate); + } + @override String toString() => _delegate.toString(); } diff --git a/packages/flutter_tools/lib/src/build_system/targets/native_assets.dart b/packages/flutter_tools/lib/src/build_system/targets/native_assets.dart index c92c1d6949581..7a5ee21788003 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/native_assets.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/native_assets.dart @@ -16,6 +16,7 @@ import '../../linux/native_assets.dart'; import '../../macos/native_assets.dart'; import '../../macos/xcode.dart'; import '../../native_assets.dart'; +import '../../windows/native_assets.dart'; import '../build_system.dart'; import '../depfile.dart'; import '../exceptions.dart'; @@ -134,6 +135,20 @@ class NativeAssets extends Target { fileSystem: fileSystem, buildRunner: buildRunner, ); + case TargetPlatform.windows_x64: + final String? environmentBuildMode = environment.defines[kBuildMode]; + if (environmentBuildMode == null) { + throw MissingDefineException(kBuildMode, name); + } + final BuildMode buildMode = BuildMode.fromCliName(environmentBuildMode); + (_, dependencies) = await buildNativeAssetsWindows( + targetPlatform: targetPlatform, + buildMode: buildMode, + projectUri: projectUri, + yamlParentDirectory: environment.buildDir.uri, + fileSystem: fileSystem, + buildRunner: buildRunner, + ); case TargetPlatform.tester: if (const LocalPlatform().isMacOS) { (_, dependencies) = await buildNativeAssetsMacOS( @@ -154,6 +169,15 @@ class NativeAssets extends Target { buildRunner: buildRunner, flutterTester: true, ); + } else if (const LocalPlatform().isWindows) { + (_, dependencies) = await buildNativeAssetsWindows( + buildMode: BuildMode.debug, + projectUri: projectUri, + yamlParentDirectory: environment.buildDir.uri, + fileSystem: fileSystem, + buildRunner: buildRunner, + flutterTester: true, + ); } else { // TODO(dacoharkes): Implement other OSes. https://github.com/flutter/flutter/issues/129757 // Write the file we claim to have in the [outputs]. @@ -168,7 +192,6 @@ class NativeAssets extends Target { case TargetPlatform.fuchsia_arm64: case TargetPlatform.fuchsia_x64: case TargetPlatform.web_javascript: - case TargetPlatform.windows_x64: // TODO(dacoharkes): Implement other OSes. https://github.com/flutter/flutter/issues/129757 // Write the file we claim to have in the [outputs]. await writeNativeAssetsYaml([], environment.buildDir.uri, fileSystem); diff --git a/packages/flutter_tools/lib/src/build_system/targets/web.dart b/packages/flutter_tools/lib/src/build_system/targets/web.dart index 1799e2c583a60..de47787895177 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/web.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/web.dart @@ -238,7 +238,8 @@ class Dart2WasmTarget extends Dart2WebTarget { ); final File depFile = environment.buildDir.childFile('dart2wasm.d'); final String dartSdkPath = artifacts.getArtifactPath(Artifact.engineDartSdkPath, platform: TargetPlatform.web_javascript); - final String dartSdkRoot = environment.fileSystem.directory(dartSdkPath).parent.path; + final String platformBinariesPath = getWebPlatformBinariesDirectory(artifacts, webRenderer).path; + final String platformFilePath = environment.fileSystem.path.join(platformBinariesPath, 'dart2wasm_platform.dill'); final List compilationArgs = [ artifacts.getArtifactPath(Artifact.engineDartAotRuntime, platform: TargetPlatform.web_javascript), @@ -246,14 +247,7 @@ class Dart2WasmTarget extends Dart2WebTarget { artifacts.getArtifactPath(Artifact.dart2wasmSnapshot, platform: TargetPlatform.web_javascript), '--packages=.dart_tool/package_config.json', '--dart-sdk=$dartSdkPath', - '--multi-root-scheme', - 'org-dartlang-sdk', - '--multi-root', - artifacts.getHostArtifact(HostArtifact.flutterWebSdk).path, - '--multi-root', - dartSdkRoot, - '--libraries-spec', - artifacts.getHostArtifact(HostArtifact.flutterWebLibrariesJson).path, + '--platform=$platformFilePath', if (buildMode == BuildMode.profile) '-Ddart.vm.profile=true' else diff --git a/packages/flutter_tools/lib/src/commands/config.dart b/packages/flutter_tools/lib/src/commands/config.dart index 9d0d3d6abfabb..0b22f065c9654 100644 --- a/packages/flutter_tools/lib/src/commands/config.dart +++ b/packages/flutter_tools/lib/src/commands/config.dart @@ -15,6 +15,11 @@ import '../runner/flutter_command_runner.dart'; class ConfigCommand extends FlutterCommand { ConfigCommand({ bool verboseHelp = false }) { + argParser.addFlag( + 'list', + help: 'List all settings and their current values.', + negatable: false, + ); argParser.addFlag('analytics', hide: !verboseHelp, help: 'Enable or disable reporting anonymously tool usage statistics and crash reports.\n' @@ -73,37 +78,7 @@ class ConfigCommand extends FlutterCommand { bool get shouldUpdateCache => false; @override - String get usageFooter { - // List all config settings. for feature flags, include whether they - // are available. - final Map featuresByName = {}; - final String channel = globals.flutterVersion.channel; - for (final Feature feature in allFeatures) { - final String? configSetting = feature.configSetting; - if (configSetting != null) { - featuresByName[configSetting] = feature; - } - } - String values = globals.config.keys - .map((String key) { - String configFooter = ''; - if (featuresByName.containsKey(key)) { - final FeatureChannelSetting setting = featuresByName[key]!.getSettingForChannel(channel); - if (!setting.available) { - configFooter = '(Unavailable)'; - } - } - return ' $key: ${globals.config.getValue(key)} $configFooter'; - }).join('\n'); - if (values.isEmpty) { - values = ' No settings have been configured.'; - } - final bool analyticsEnabled = globals.flutterUsage.enabled && - !globals.flutterUsage.suppressAnalytics; - return - '\nSettings:\n$values\n\n' - 'Analytics reporting is currently ${analyticsEnabled ? 'enabled' : 'disabled'}.'; - } + String get usageFooter => '\n$analyticsUsage'; /// Return null to disable analytics recording of the `config` command. @override @@ -121,6 +96,11 @@ class ConfigCommand extends FlutterCommand { ' flutter config --android-studio-dir "/opt/Android Studio"'); } + if (boolArg('list')) { + globals.printStatus(settingsText); + return FlutterCommandResult.success(); + } + if (boolArg('machine')) { await handleMachine(); return FlutterCommandResult.success(); @@ -133,6 +113,7 @@ class ConfigCommand extends FlutterCommand { globals.config.removeValue(configSetting); } } + globals.printStatus(requireReloadTipText); return FlutterCommandResult.success(); } @@ -195,7 +176,7 @@ class ConfigCommand extends FlutterCommand { if (argResults == null || argResults!.arguments.isEmpty) { globals.printStatus(usage); } else { - globals.printStatus('\nYou may need to restart any open editors for them to read new settings.'); + globals.printStatus('\n$requireReloadTipText'); } return FlutterCommandResult.success(); @@ -234,4 +215,50 @@ class ConfigCommand extends FlutterCommand { globals.printStatus('Setting "$keyName" value to "$keyValue".'); } } + + /// List all config settings. for feature flags, include whether they are available. + String get settingsText { + final Map featuresByName = {}; + final String channel = globals.flutterVersion.channel; + for (final Feature feature in allFeatures) { + final String? configSetting = feature.configSetting; + if (configSetting != null) { + featuresByName[configSetting] = feature; + } + } + final Set keys = { + ...allFeatures.map((Feature e) => e.configSetting).whereType(), + ...globals.config.keys, + }; + final Iterable settings = keys.map((String key) { + Object? value = globals.config.getValue(key); + value ??= '(Not set)'; + final StringBuffer buffer = StringBuffer(' $key: $value'); + if (featuresByName.containsKey(key)) { + final FeatureChannelSetting setting = featuresByName[key]!.getSettingForChannel(channel); + if (!setting.available) { + buffer.write(' (Unavailable)'); + } + } + return buffer.toString(); + }); + final StringBuffer buffer = StringBuffer(); + buffer.writeln('All Settings:'); + if (settings.isEmpty) { + buffer.writeln(' No configs have been configured.'); + } else { + buffer.writeln(settings.join('\n')); + } + return buffer.toString(); + } + + /// List the status of the analytics reporting. + String get analyticsUsage { + final bool analyticsEnabled = + globals.flutterUsage.enabled && !globals.flutterUsage.suppressAnalytics; + return 'Analytics reporting is currently ${analyticsEnabled ? 'enabled' : 'disabled'}.'; + } + + /// Raising the reload tip for setting changes. + final String requireReloadTipText = 'You may need to restart any open editors for them to read new settings.'; } diff --git a/packages/flutter_tools/lib/src/commands/screenshot.dart b/packages/flutter_tools/lib/src/commands/screenshot.dart index 21b531ecf597b..db3686e49f6b1 100644 --- a/packages/flutter_tools/lib/src/commands/screenshot.dart +++ b/packages/flutter_tools/lib/src/commands/screenshot.dart @@ -18,7 +18,6 @@ const String _kType = 'type'; const String _kVmServiceUrl = 'vm-service-url'; const String _kDeviceType = 'device'; const String _kSkiaType = 'skia'; -const String _kRasterizerType = 'rasterizer'; class ScreenshotCommand extends FlutterCommand { ScreenshotCommand({required this.fs}) { @@ -33,7 +32,7 @@ class ScreenshotCommand extends FlutterCommand { aliases: [ 'observatory-url' ], // for historical reasons valueHelp: 'URI', help: 'The VM Service URL to which to connect.\n' - 'This is required when "--$_kType" is "$_kSkiaType" or "$_kRasterizerType".\n' + 'This is required when "--$_kType" is "$_kSkiaType".\n' 'To find the VM service URL, use "flutter run" and look for ' '"A Dart VM Service ... is available at" in the output.', ); @@ -41,13 +40,12 @@ class ScreenshotCommand extends FlutterCommand { _kType, valueHelp: 'type', help: 'The type of screenshot to retrieve.', - allowed: const [_kDeviceType, _kSkiaType, _kRasterizerType], + allowed: const [_kDeviceType, _kSkiaType], allowedHelp: const { _kDeviceType: "Delegate to the device's native screenshot capabilities. This " 'screenshots the entire screen currently being displayed (including content ' 'not rendered by Flutter, like the device status bar).', _kSkiaType: 'Render the Flutter app as a Skia picture. Requires "--$_kVmServiceUrl".', - _kRasterizerType: 'Render the Flutter app using the rasterizer. Requires "--$_kVmServiceUrl."', }, defaultsTo: _kDeviceType, ); @@ -116,8 +114,6 @@ class ScreenshotCommand extends FlutterCommand { await runScreenshot(outputFile); case _kSkiaType: success = await runSkia(outputFile); - case _kRasterizerType: - success = await runRasterizer(outputFile); } return success ? FlutterCommandResult.success() @@ -173,30 +169,6 @@ class ScreenshotCommand extends FlutterCommand { return true; } - Future runRasterizer(File? outputFile) async { - final Uri vmServiceUrl = Uri.parse(stringArg(_kVmServiceUrl)!); - final FlutterVmService vmService = await connectToVmService(vmServiceUrl, logger: globals.logger); - final vm_service.Response? response = await vmService.screenshot(); - if (response == null) { - globals.printError( - 'The screenshot request failed, probably because the device was ' - 'disconnected', - ); - return false; - } - outputFile ??= globals.fsUtils.getUniqueFile( - fs.currentDirectory, - 'flutter', - 'png', - ); - final IOSink sink = outputFile.openWrite(); - sink.add(base64.decode(response.json?['screenshot'] as String)); - await sink.close(); - _showOutputFileInfo(outputFile); - ensureOutputIsNotJsonRpcError(outputFile); - return true; - } - static void checkOutput(File outputFile, FileSystem fs) { if (!fs.file(outputFile.path).existsSync()) { throwToolExit( diff --git a/packages/flutter_tools/lib/src/commands/update_packages.dart b/packages/flutter_tools/lib/src/commands/update_packages.dart index e482057c56fa7..03c9f82fa958e 100644 --- a/packages/flutter_tools/lib/src/commands/update_packages.dart +++ b/packages/flutter_tools/lib/src/commands/update_packages.dart @@ -36,6 +36,10 @@ const Map kManuallyPinnedDependencies = { 'material_color_utilities': '0.5.0', // https://github.com/flutter/flutter/issues/115660 'archive': '3.3.2', + // https://github.com/flutter/devtools/issues/3951 + 'leak_tracker': '9.0.8', + // https://github.com/flutter/devtools/issues/3951 + 'leak_tracker_flutter_testing': '1.0.6', }; class UpdatePackagesCommand extends FlutterCommand { diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart index a5a4f92c25048..1c412832016b3 100644 --- a/packages/flutter_tools/lib/src/context_runner.dart +++ b/packages/flutter_tools/lib/src/context_runner.dart @@ -61,6 +61,7 @@ import 'persistent_tool_state.dart'; import 'reporting/crash_reporting.dart'; import 'reporting/first_run.dart'; import 'reporting/reporting.dart'; +import 'reporting/unified_analytics.dart'; import 'resident_runner.dart'; import 'run_hot.dart'; import 'runner/local_engine.dart'; @@ -88,11 +89,10 @@ Future runInContext( body: runnerWrapper, overrides: overrides, fallbacks: { - Analytics: () => Analytics( - tool: DashTool.flutterTool, - flutterChannel: globals.flutterVersion.channel, - flutterVersion: globals.flutterVersion.frameworkVersion, - dartVersion: globals.flutterVersion.dartSdkVersion, + Analytics: () => getAnalytics( + runningOnBot: runningOnBot, + flutterVersion: globals.flutterVersion, + environment: globals.platform.environment, ), AndroidBuilder: () => AndroidGradleBuilder( java: globals.java, diff --git a/packages/flutter_tools/lib/src/ios/native_assets.dart b/packages/flutter_tools/lib/src/ios/native_assets.dart index 21ddb2c5e5177..8a18b9eb14765 100644 --- a/packages/flutter_tools/lib/src/ios/native_assets.dart +++ b/packages/flutter_tools/lib/src/ios/native_assets.dart @@ -27,7 +27,7 @@ Future dryRunNativeAssetsIOS({ return null; } - final Uri buildUri_ = nativeAssetsBuildUri(projectUri, OS.iOS); + final Uri buildUri = nativeAssetsBuildUri(projectUri, OS.iOS); final Iterable assetTargetLocations = await dryRunNativeAssetsIOSInternal( fileSystem, projectUri, @@ -35,7 +35,7 @@ Future dryRunNativeAssetsIOS({ ); final Uri nativeAssetsUri = await writeNativeAssetsYaml( assetTargetLocations, - buildUri_, + buildUri, fileSystem, ); return nativeAssetsUri; @@ -46,17 +46,17 @@ Future> dryRunNativeAssetsIOSInternal( Uri projectUri, NativeAssetsBuildRunner buildRunner, ) async { - const OS targetOs = OS.iOS; - globals.logger.printTrace('Dry running native assets for $targetOs.'); + const OS targetOS = OS.iOS; + globals.logger.printTrace('Dry running native assets for $targetOS.'); final List nativeAssets = (await buildRunner.dryRun( linkModePreference: LinkModePreference.dynamic, - targetOs: targetOs, + targetOS: targetOS, workingDirectory: projectUri, includeParentEnvironment: true, )) .assets; ensureNoLinkModeStatic(nativeAssets); - globals.logger.printTrace('Dry running native assets for $targetOs done.'); + globals.logger.printTrace('Dry running native assets for $targetOS done.'); final Iterable assetTargetLocations = _assetTargetLocations(nativeAssets).values; return assetTargetLocations; } @@ -80,8 +80,8 @@ Future> buildNativeAssetsIOS({ final List targets = darwinArchs.map(_getNativeTarget).toList(); final native_assets_cli.BuildMode buildModeCli = nativeAssetsBuildMode(buildMode); - const OS targetOs = OS.iOS; - final Uri buildUri_ = nativeAssetsBuildUri(projectUri, targetOs); + const OS targetOS = OS.iOS; + final Uri buildUri = nativeAssetsBuildUri(projectUri, targetOS); final IOSSdk iosSdk = _getIOSSdk(environmentType); globals.logger.printTrace('Building native assets for $targets $buildModeCli.'); @@ -104,7 +104,7 @@ Future> buildNativeAssetsIOS({ globals.logger.printTrace('Building native assets for $targets done.'); final Map> fatAssetTargetLocations = _fatAssetTargetLocations(nativeAssets); await copyNativeAssetsMacOSHost( - buildUri_, + buildUri, fatAssetTargetLocations, codesignIdentity, buildMode, diff --git a/packages/flutter_tools/lib/src/linux/native_assets.dart b/packages/flutter_tools/lib/src/linux/native_assets.dart index 6c52a33707c3f..692c4126ac830 100644 --- a/packages/flutter_tools/lib/src/linux/native_assets.dart +++ b/packages/flutter_tools/lib/src/linux/native_assets.dart @@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:native_assets_builder/native_assets_builder.dart' show BuildResult; import 'package:native_assets_cli/native_assets_cli.dart' hide BuildMode; -import 'package:native_assets_cli/native_assets_cli.dart' as native_assets_cli; import '../base/common.dart'; import '../base/file_system.dart'; @@ -22,24 +20,14 @@ Future dryRunNativeAssetsLinux({ required Uri projectUri, bool flutterTester = false, required FileSystem fileSystem, -}) async { - if (!await nativeBuildRequired(buildRunner)) { - return null; - } - - final Uri buildUri_ = nativeAssetsBuildUri(projectUri, OS.linux); - final Iterable nativeAssetPaths = await dryRunNativeAssetsLinuxInternal( - fileSystem, - projectUri, - flutterTester, - buildRunner, - ); - final Uri nativeAssetsUri = await writeNativeAssetsYaml( - nativeAssetPaths, - buildUri_, - fileSystem, +}) { + return dryRunNativeAssetsSingleArchitecture( + buildRunner: buildRunner, + projectUri: projectUri, + flutterTester: flutterTester, + fileSystem: fileSystem, + os: OS.linux, ); - return nativeAssetsUri; } Future> dryRunNativeAssetsLinuxInternal( @@ -47,33 +35,16 @@ Future> dryRunNativeAssetsLinuxInternal( Uri projectUri, bool flutterTester, NativeAssetsBuildRunner buildRunner, -) async { - const OS targetOs = OS.linux; - final Uri buildUri_ = nativeAssetsBuildUri(projectUri, targetOs); - - globals.logger.printTrace('Dry running native assets for $targetOs.'); - final List nativeAssets = (await buildRunner.dryRun( - linkModePreference: LinkModePreference.dynamic, - targetOs: targetOs, - workingDirectory: projectUri, - includeParentEnvironment: true, - )) - .assets; - ensureNoLinkModeStatic(nativeAssets); - globals.logger.printTrace('Dry running native assets for $targetOs done.'); - final Uri? absolutePath = flutterTester ? buildUri_ : null; - final Map assetTargetLocations = _assetTargetLocations(nativeAssets, absolutePath); - final Iterable nativeAssetPaths = assetTargetLocations.values; - return nativeAssetPaths; +) { + return dryRunNativeAssetsSingleArchitectureInternal( + fileSystem, + projectUri, + flutterTester, + buildRunner, + OS.linux, + ); } -/// Builds native assets. -/// -/// If [targetPlatform] is omitted, the current target architecture is used. -/// -/// If [flutterTester] is true, absolute paths are emitted in the native -/// assets mapping. This can be used for JIT mode without sandbox on the host. -/// This is used in `flutter test` and `flutter run -d flutter-tester`. Future<(Uri? nativeAssetsYaml, List dependencies)> buildNativeAssetsLinux({ required NativeAssetsBuildRunner buildRunner, TargetPlatform? targetPlatform, @@ -82,127 +53,16 @@ Future<(Uri? nativeAssetsYaml, List dependencies)> buildNativeAssetsLinux({ bool flutterTester = false, Uri? yamlParentDirectory, required FileSystem fileSystem, -}) async { - const OS targetOs = OS.linux; - final Uri buildUri_ = nativeAssetsBuildUri(projectUri, targetOs); - final Directory buildDir = fileSystem.directory(buildUri_); - if (!await buildDir.exists()) { - // CMake requires the folder to exist to do copying. - await buildDir.create(recursive: true); - } - if (!await nativeBuildRequired(buildRunner)) { - final Uri nativeAssetsYaml = await writeNativeAssetsYaml([], yamlParentDirectory ?? buildUri_, fileSystem); - return (nativeAssetsYaml, []); - } - - final Target target = targetPlatform != null ? _getNativeTarget(targetPlatform) : Target.current; - final native_assets_cli.BuildMode buildModeCli = nativeAssetsBuildMode(buildMode); - - globals.logger.printTrace('Building native assets for $target $buildModeCli.'); - final BuildResult result = await buildRunner.build( - linkModePreference: LinkModePreference.dynamic, - target: target, - buildMode: buildModeCli, - workingDirectory: projectUri, - includeParentEnvironment: true, - cCompilerConfig: await buildRunner.cCompilerConfig, - ); - final List nativeAssets = result.assets; - final Set dependencies = result.dependencies.toSet(); - ensureNoLinkModeStatic(nativeAssets); - globals.logger.printTrace('Building native assets for $target done.'); - final Uri? absolutePath = flutterTester ? buildUri_ : null; - final Map assetTargetLocations = _assetTargetLocations(nativeAssets, absolutePath); - await _copyNativeAssetsLinux( - buildUri_, - assetTargetLocations, - buildMode, - fileSystem, - ); - final Uri nativeAssetsUri = await writeNativeAssetsYaml( - assetTargetLocations.values, - yamlParentDirectory ?? buildUri_, - fileSystem, +}) { + return buildNativeAssetsSingleArchitecture( + buildRunner: buildRunner, + targetPlatform: targetPlatform, + projectUri: projectUri, + buildMode: buildMode, + flutterTester: flutterTester, + yamlParentDirectory: yamlParentDirectory, + fileSystem: fileSystem, ); - return (nativeAssetsUri, dependencies.toList()); -} - -Map _assetTargetLocations( - List nativeAssets, - Uri? absolutePath, -) => - { - for (final Asset asset in nativeAssets) asset: _targetLocationLinux(asset, absolutePath), - }; - -Asset _targetLocationLinux(Asset asset, Uri? absolutePath) { - final AssetPath path = asset.path; - switch (path) { - case AssetSystemPath _: - case AssetInExecutable _: - case AssetInProcess _: - return asset; - case AssetAbsolutePath _: - final String fileName = path.uri.pathSegments.last; - Uri uri; - if (absolutePath != null) { - // Flutter tester needs full host paths. - uri = absolutePath.resolve(fileName); - } else { - // Flutter Desktop needs "absolute" paths inside the app. - // "relative" in the context of native assets would be relative to the - // kernel or aot snapshot. - uri = Uri(path: fileName); - } - return asset.copyWith(path: AssetAbsolutePath(uri)); - } - throw Exception('Unsupported asset path type ${path.runtimeType} in asset $asset'); -} - -/// Extract the [Target] from a [TargetPlatform]. -Target _getNativeTarget(TargetPlatform targetPlatform) { - switch (targetPlatform) { - case TargetPlatform.linux_x64: - return Target.linuxX64; - case TargetPlatform.linux_arm64: - return Target.linuxArm64; - case TargetPlatform.android: - case TargetPlatform.ios: - case TargetPlatform.darwin: - case TargetPlatform.windows_x64: - case TargetPlatform.fuchsia_arm64: - case TargetPlatform.fuchsia_x64: - case TargetPlatform.tester: - case TargetPlatform.web_javascript: - case TargetPlatform.android_arm: - case TargetPlatform.android_arm64: - case TargetPlatform.android_x64: - case TargetPlatform.android_x86: - throw Exception('Unknown targetPlatform: $targetPlatform.'); - } -} - -Future _copyNativeAssetsLinux( - Uri buildUri, - Map assetTargetLocations, - BuildMode buildMode, - FileSystem fileSystem, -) async { - if (assetTargetLocations.isNotEmpty) { - globals.logger.printTrace('Copying native assets to ${buildUri.toFilePath()}.'); - final Directory buildDir = fileSystem.directory(buildUri.toFilePath()); - if (!buildDir.existsSync()) { - buildDir.createSync(recursive: true); - } - for (final MapEntry assetMapping in assetTargetLocations.entries) { - final Uri source = (assetMapping.key.path as AssetAbsolutePath).uri; - final Uri target = (assetMapping.value.path as AssetAbsolutePath).uri; - final Uri targetUri = buildUri.resolveUri(target); - final String targetFullPath = targetUri.toFilePath(); - await fileSystem.file(source).copy(targetFullPath); - } - globals.logger.printTrace('Copying native assets done.'); - } } /// Flutter expects `clang++` to be on the path on Linux hosts. diff --git a/packages/flutter_tools/lib/src/macos/native_assets.dart b/packages/flutter_tools/lib/src/macos/native_assets.dart index 1bdf27d76ffab..5e79097f2ca03 100644 --- a/packages/flutter_tools/lib/src/macos/native_assets.dart +++ b/packages/flutter_tools/lib/src/macos/native_assets.dart @@ -27,9 +27,9 @@ Future dryRunNativeAssetsMacOS({ return null; } - final Uri buildUri_ = nativeAssetsBuildUri(projectUri, OS.macOS); + final Uri buildUri = nativeAssetsBuildUri(projectUri, OS.macOS); final Iterable nativeAssetPaths = await dryRunNativeAssetsMacOSInternal(fileSystem, projectUri, flutterTester, buildRunner); - final Uri nativeAssetsUri = await writeNativeAssetsYaml(nativeAssetPaths, buildUri_, fileSystem); + final Uri nativeAssetsUri = await writeNativeAssetsYaml(nativeAssetPaths, buildUri, fileSystem); return nativeAssetsUri; } @@ -39,20 +39,20 @@ Future> dryRunNativeAssetsMacOSInternal( bool flutterTester, NativeAssetsBuildRunner buildRunner, ) async { - const OS targetOs = OS.macOS; - final Uri buildUri_ = nativeAssetsBuildUri(projectUri, targetOs); + const OS targetOS = OS.macOS; + final Uri buildUri = nativeAssetsBuildUri(projectUri, targetOS); - globals.logger.printTrace('Dry running native assets for $targetOs.'); + globals.logger.printTrace('Dry running native assets for $targetOS.'); final List nativeAssets = (await buildRunner.dryRun( linkModePreference: LinkModePreference.dynamic, - targetOs: targetOs, + targetOS: targetOS, workingDirectory: projectUri, includeParentEnvironment: true, )) .assets; ensureNoLinkModeStatic(nativeAssets); - globals.logger.printTrace('Dry running native assets for $targetOs done.'); - final Uri? absolutePath = flutterTester ? buildUri_ : null; + globals.logger.printTrace('Dry running native assets for $targetOS done.'); + final Uri? absolutePath = flutterTester ? buildUri : null; final Map assetTargetLocations = _assetTargetLocations(nativeAssets, absolutePath); final Iterable nativeAssetPaths = assetTargetLocations.values; return nativeAssetPaths; @@ -75,10 +75,10 @@ Future<(Uri? nativeAssetsYaml, List dependencies)> buildNativeAssetsMacOS({ Uri? yamlParentDirectory, required FileSystem fileSystem, }) async { - const OS targetOs = OS.macOS; - final Uri buildUri_ = nativeAssetsBuildUri(projectUri, targetOs); + const OS targetOS = OS.macOS; + final Uri buildUri = nativeAssetsBuildUri(projectUri, targetOS); if (!await nativeBuildRequired(buildRunner)) { - final Uri nativeAssetsYaml = await writeNativeAssetsYaml([], yamlParentDirectory ?? buildUri_, fileSystem); + final Uri nativeAssetsYaml = await writeNativeAssetsYaml([], yamlParentDirectory ?? buildUri, fileSystem); return (nativeAssetsYaml, []); } @@ -102,11 +102,11 @@ Future<(Uri? nativeAssetsYaml, List dependencies)> buildNativeAssetsMacOS({ } ensureNoLinkModeStatic(nativeAssets); globals.logger.printTrace('Building native assets for $targets done.'); - final Uri? absolutePath = flutterTester ? buildUri_ : null; + final Uri? absolutePath = flutterTester ? buildUri : null; final Map assetTargetLocations = _assetTargetLocations(nativeAssets, absolutePath); final Map> fatAssetTargetLocations = _fatAssetTargetLocations(nativeAssets, absolutePath); - await copyNativeAssetsMacOSHost(buildUri_, fatAssetTargetLocations, codesignIdentity, buildMode, fileSystem); - final Uri nativeAssetsUri = await writeNativeAssetsYaml(assetTargetLocations.values, yamlParentDirectory ?? buildUri_, fileSystem); + await copyNativeAssetsMacOSHost(buildUri, fatAssetTargetLocations, codesignIdentity, buildMode, fileSystem); + final Uri nativeAssetsUri = await writeNativeAssetsYaml(assetTargetLocations.values, yamlParentDirectory ?? buildUri, fileSystem); return (nativeAssetsUri, dependencies.toList()); } diff --git a/packages/flutter_tools/lib/src/migrations/cmake_native_assets_migration.dart b/packages/flutter_tools/lib/src/migrations/cmake_native_assets_migration.dart index fe9ba86a035ac..c7f21351afbbd 100644 --- a/packages/flutter_tools/lib/src/migrations/cmake_native_assets_migration.dart +++ b/packages/flutter_tools/lib/src/migrations/cmake_native_assets_migration.dart @@ -41,8 +41,8 @@ class CmakeNativeAssetsMigration extends ProjectMigrator { # Copy the native assets provided by the build.dart from all packages. set(NATIVE_ASSETS_DIR "\${PROJECT_BUILD_DIR}native_assets/$os/") install(DIRECTORY "\${NATIVE_ASSETS_DIR}" - DESTINATION "\${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) + DESTINATION "\${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) '''; // Insert the new command after the bundled libraries loop. diff --git a/packages/flutter_tools/lib/src/native_assets.dart b/packages/flutter_tools/lib/src/native_assets.dart index caeffa356333e..38afb4e6e60d8 100644 --- a/packages/flutter_tools/lib/src/native_assets.dart +++ b/packages/flutter_tools/lib/src/native_assets.dart @@ -23,6 +23,7 @@ import 'linux/native_assets.dart'; import 'macos/native_assets.dart'; import 'macos/native_assets_host.dart'; import 'resident_runner.dart'; +import 'windows/native_assets.dart'; /// Programmatic API to be used by Dart launchers to invoke native builds. /// @@ -42,7 +43,7 @@ abstract class NativeAssetsBuildRunner { Future dryRun({ required bool includeParentEnvironment, required LinkModePreference linkModePreference, - required OS targetOs, + required OS targetOS, required Uri workingDirectory, }); @@ -100,10 +101,8 @@ class NativeAssetsBuildRunnerImpl implements NativeAssetsBuildRunner { @override Future hasPackageConfig() { - final File packageConfigJson = fileSystem - .directory(projectUri.toFilePath()) - .childDirectory('.dart_tool') - .childFile('package_config.json'); + final File packageConfigJson = + fileSystem.directory(projectUri.toFilePath()).childDirectory('.dart_tool').childFile('package_config.json'); return packageConfigJson.exists(); } @@ -120,7 +119,7 @@ class NativeAssetsBuildRunnerImpl implements NativeAssetsBuildRunner { Future dryRun({ required bool includeParentEnvironment, required LinkModePreference linkModePreference, - required OS targetOs, + required OS targetOS, required Uri workingDirectory, }) { final PackageLayout packageLayout = PackageLayout.fromPackageConfig( @@ -130,7 +129,7 @@ class NativeAssetsBuildRunnerImpl implements NativeAssetsBuildRunner { return _buildRunner.dryRun( includeParentEnvironment: includeParentEnvironment, linkModePreference: linkModePreference, - targetOs: targetOs, + targetOs: targetOS, workingDirectory: workingDirectory, packageLayout: packageLayout, ); @@ -172,8 +171,11 @@ class NativeAssetsBuildRunnerImpl implements NativeAssetsBuildRunner { if (globals.platform.isLinux) { return cCompilerConfigLinux(); } + if (globals.platform.isWindows) { + return cCompilerConfigWindows(); + } throwToolExit( - 'Native assets feature not yet implemented for Linux, Windows and Android.', + 'Native assets feature not yet implemented for Android.', ); }(); } @@ -343,6 +345,13 @@ Future dryRunNativeAssets({ fileSystem: fileSystem, buildRunner: buildRunner, ); + } else if (const LocalPlatform().isWindows) { + nativeAssetsYaml = await dryRunNativeAssetsWindows( + projectUri: projectUri, + flutterTester: true, + fileSystem: fileSystem, + buildRunner: buildRunner, + ); } else { await nativeBuildRequired(buildRunner); nativeAssetsYaml = null; @@ -354,6 +363,12 @@ Future dryRunNativeAssets({ fileSystem: fileSystem, buildRunner: buildRunner, ); + case build_info.TargetPlatform.windows_x64: + nativeAssetsYaml = await dryRunNativeAssetsWindows( + projectUri: projectUri, + fileSystem: fileSystem, + buildRunner: buildRunner, + ); case build_info.TargetPlatform.android_arm: case build_info.TargetPlatform.android_arm64: case build_info.TargetPlatform.android_x64: @@ -362,7 +377,6 @@ Future dryRunNativeAssets({ case build_info.TargetPlatform.fuchsia_arm64: case build_info.TargetPlatform.fuchsia_x64: case build_info.TargetPlatform.web_javascript: - case build_info.TargetPlatform.windows_x64: await ensureNoNativeAssetsOrOsIsSupported( projectUri, targetPlatform.toString(), @@ -387,19 +401,41 @@ Future dryRunNativeAssetsMultipeOSes({ return null; } - final Uri buildUri_ = buildUriMultiple(projectUri); + final Uri buildUri = buildUriMultiple(projectUri); final Iterable nativeAssetPaths = [ if (targetPlatforms.contains(build_info.TargetPlatform.darwin) || (targetPlatforms.contains(build_info.TargetPlatform.tester) && OS.current == OS.macOS)) - ...await dryRunNativeAssetsMacOSInternal(fileSystem, projectUri, false, buildRunner), + ...await dryRunNativeAssetsMacOSInternal( + fileSystem, + projectUri, + false, + buildRunner, + ), if (targetPlatforms.contains(build_info.TargetPlatform.linux_arm64) || targetPlatforms.contains(build_info.TargetPlatform.linux_x64) || (targetPlatforms.contains(build_info.TargetPlatform.tester) && OS.current == OS.linux)) - ...await dryRunNativeAssetsLinuxInternal(fileSystem, projectUri, false, buildRunner), + ...await dryRunNativeAssetsLinuxInternal( + fileSystem, + projectUri, + false, + buildRunner, + ), + if (targetPlatforms.contains(build_info.TargetPlatform.windows_x64) || + (targetPlatforms.contains(build_info.TargetPlatform.tester) && OS.current == OS.windows)) + ...await dryRunNativeAssetsWindowsInternal( + fileSystem, + projectUri, + false, + buildRunner, + ), if (targetPlatforms.contains(build_info.TargetPlatform.ios)) - ...await dryRunNativeAssetsIOSInternal(fileSystem, projectUri, buildRunner) + ...await dryRunNativeAssetsIOSInternal( + fileSystem, + projectUri, + buildRunner, + ) ]; - final Uri nativeAssetsUri = await writeNativeAssetsYaml(nativeAssetPaths, buildUri_, fileSystem); + final Uri nativeAssetsUri = await writeNativeAssetsYaml(nativeAssetPaths, buildUri, fileSystem); return nativeAssetsUri; } @@ -409,3 +445,213 @@ Uri buildUriMultiple(Uri projectUri) { final String buildDir = build_info.getBuildDirectory(); return projectUri.resolve('$buildDir/native_assets/multiple/'); } + +/// Dry run the native builds. +/// +/// This does not build native assets, it only simulates what the final paths +/// of all assets will be so that this can be embedded in the kernel file. +Future dryRunNativeAssetsSingleArchitecture({ + required NativeAssetsBuildRunner buildRunner, + required Uri projectUri, + bool flutterTester = false, + required FileSystem fileSystem, + required OS os, +}) async { + if (!await nativeBuildRequired(buildRunner)) { + return null; + } + + final Uri buildUri = nativeAssetsBuildUri(projectUri, os); + final Iterable nativeAssetPaths = await dryRunNativeAssetsSingleArchitectureInternal( + fileSystem, + projectUri, + flutterTester, + buildRunner, + os, + ); + final Uri nativeAssetsUri = await writeNativeAssetsYaml( + nativeAssetPaths, + buildUri, + fileSystem, + ); + return nativeAssetsUri; +} + +Future> dryRunNativeAssetsSingleArchitectureInternal( + FileSystem fileSystem, + Uri projectUri, + bool flutterTester, + NativeAssetsBuildRunner buildRunner, + OS targetOS, +) async { + final Uri buildUri = nativeAssetsBuildUri(projectUri, targetOS); + + globals.logger.printTrace('Dry running native assets for $targetOS.'); + final List nativeAssets = (await buildRunner.dryRun( + linkModePreference: LinkModePreference.dynamic, + targetOS: targetOS, + workingDirectory: projectUri, + includeParentEnvironment: true, + )) + .assets; + ensureNoLinkModeStatic(nativeAssets); + globals.logger.printTrace('Dry running native assets for $targetOS done.'); + final Uri? absolutePath = flutterTester ? buildUri : null; + final Map assetTargetLocations = _assetTargetLocationsSingleArchitecture( + nativeAssets, + absolutePath, + ); + final Iterable nativeAssetPaths = assetTargetLocations.values; + return nativeAssetPaths; +} + +/// Builds native assets. +/// +/// If [targetPlatform] is omitted, the current target architecture is used. +/// +/// If [flutterTester] is true, absolute paths are emitted in the native +/// assets mapping. This can be used for JIT mode without sandbox on the host. +/// This is used in `flutter test` and `flutter run -d flutter-tester`. +Future<(Uri? nativeAssetsYaml, List dependencies)> buildNativeAssetsSingleArchitecture({ + required NativeAssetsBuildRunner buildRunner, + build_info.TargetPlatform? targetPlatform, + required Uri projectUri, + required build_info.BuildMode buildMode, + bool flutterTester = false, + Uri? yamlParentDirectory, + required FileSystem fileSystem, +}) async { + final Target target = targetPlatform != null ? _getNativeTarget(targetPlatform) : Target.current; + final OS targetOS = target.os; + final Uri buildUri = nativeAssetsBuildUri(projectUri, targetOS); + final Directory buildDir = fileSystem.directory(buildUri); + if (!await buildDir.exists()) { + // CMake requires the folder to exist to do copying. + await buildDir.create(recursive: true); + } + if (!await nativeBuildRequired(buildRunner)) { + final Uri nativeAssetsYaml = await writeNativeAssetsYaml( + [], + yamlParentDirectory ?? buildUri, + fileSystem, + ); + return (nativeAssetsYaml, []); + } + + final BuildMode buildModeCli = nativeAssetsBuildMode(buildMode); + + globals.logger.printTrace('Building native assets for $target $buildModeCli.'); + final BuildResult result = await buildRunner.build( + linkModePreference: LinkModePreference.dynamic, + target: target, + buildMode: buildModeCli, + workingDirectory: projectUri, + includeParentEnvironment: true, + cCompilerConfig: await buildRunner.cCompilerConfig, + ); + final List nativeAssets = result.assets; + final Set dependencies = result.dependencies.toSet(); + ensureNoLinkModeStatic(nativeAssets); + globals.logger.printTrace('Building native assets for $target done.'); + final Uri? absolutePath = flutterTester ? buildUri : null; + final Map assetTargetLocations = _assetTargetLocationsSingleArchitecture(nativeAssets, absolutePath); + await _copyNativeAssetsSingleArchitecture( + buildUri, + assetTargetLocations, + buildMode, + fileSystem, + ); + final Uri nativeAssetsUri = await writeNativeAssetsYaml( + assetTargetLocations.values, + yamlParentDirectory ?? buildUri, + fileSystem, + ); + return (nativeAssetsUri, dependencies.toList()); +} + +Map _assetTargetLocationsSingleArchitecture( + List nativeAssets, + Uri? absolutePath, +) { + return { + for (final Asset asset in nativeAssets) + asset: _targetLocationSingleArchitecture( + asset, + absolutePath, + ), + }; +} + +Asset _targetLocationSingleArchitecture(Asset asset, Uri? absolutePath) { + final AssetPath path = asset.path; + switch (path) { + case AssetSystemPath _: + case AssetInExecutable _: + case AssetInProcess _: + return asset; + case AssetAbsolutePath _: + final String fileName = path.uri.pathSegments.last; + Uri uri; + if (absolutePath != null) { + // Flutter tester needs full host paths. + uri = absolutePath.resolve(fileName); + } else { + // Flutter Desktop needs "absolute" paths inside the app. + // "relative" in the context of native assets would be relative to the + // kernel or aot snapshot. + uri = Uri(path: fileName); + } + return asset.copyWith(path: AssetAbsolutePath(uri)); + } + throw Exception('Unsupported asset path type ${path.runtimeType} in asset $asset'); +} + +/// Extract the [Target] from a [TargetPlatform]. +/// +/// Does not cover MacOS, iOS, and Android as these pass the architecture +/// in other enums. +Target _getNativeTarget(build_info.TargetPlatform targetPlatform) { + switch (targetPlatform) { + case build_info.TargetPlatform.linux_x64: + return Target.linuxX64; + case build_info.TargetPlatform.linux_arm64: + return Target.linuxArm64; + case build_info.TargetPlatform.windows_x64: + return Target.windowsX64; + case build_info.TargetPlatform.android: + case build_info.TargetPlatform.ios: + case build_info.TargetPlatform.darwin: + case build_info.TargetPlatform.fuchsia_arm64: + case build_info.TargetPlatform.fuchsia_x64: + case build_info.TargetPlatform.tester: + case build_info.TargetPlatform.web_javascript: + case build_info.TargetPlatform.android_arm: + case build_info.TargetPlatform.android_arm64: + case build_info.TargetPlatform.android_x64: + case build_info.TargetPlatform.android_x86: + throw Exception('Unknown targetPlatform: $targetPlatform.'); + } +} + +Future _copyNativeAssetsSingleArchitecture( + Uri buildUri, + Map assetTargetLocations, + build_info.BuildMode buildMode, + FileSystem fileSystem, +) async { + if (assetTargetLocations.isNotEmpty) { + globals.logger.printTrace('Copying native assets to ${buildUri.toFilePath()}.'); + final Directory buildDir = fileSystem.directory(buildUri.toFilePath()); + if (!buildDir.existsSync()) { + buildDir.createSync(recursive: true); + } + for (final MapEntry assetMapping in assetTargetLocations.entries) { + final Uri source = (assetMapping.key.path as AssetAbsolutePath).uri; + final Uri target = (assetMapping.value.path as AssetAbsolutePath).uri; + final Uri targetUri = buildUri.resolveUri(target); + final String targetFullPath = targetUri.toFilePath(); + await fileSystem.file(source).copy(targetFullPath); + } + globals.logger.printTrace('Copying native assets done.'); + } +} diff --git a/packages/flutter_tools/lib/src/reporting/unified_analytics.dart b/packages/flutter_tools/lib/src/reporting/unified_analytics.dart new file mode 100644 index 0000000000000..767397dbb7a10 --- /dev/null +++ b/packages/flutter_tools/lib/src/reporting/unified_analytics.dart @@ -0,0 +1,52 @@ +// Copyright 2014 The Flutter 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:unified_analytics/unified_analytics.dart'; + +import '../version.dart'; + +/// This function is called from within the context runner to perform +/// checks that are necessary for determining if a no-op version of +/// [Analytics] gets returned. +/// +/// When [enableAsserts] is set to `true`, various assert statements +/// will be enabled to ensure usage of this class is within GA4 limitations. +/// +/// For testing purposes, pass in a [FakeAnalytics] instance initialized with +/// an in-memory [FileSystem] to prevent writing to disk. +Analytics getAnalytics({ + required bool runningOnBot, + required FlutterVersion flutterVersion, + required Map environment, + bool enableAsserts = false, + FakeAnalytics? analyticsOverride, +}) { + final String version = flutterVersion.getVersionString(redactUnknownBranches: true); + final bool suppressEnvFlag = environment['FLUTTER_SUPPRESS_ANALYTICS']?.toLowerCase() == 'true'; + + if (// Ignore local user branches. + version.startsWith('[user-branch]') || + // Many CI systems don't do a full git checkout. + version.endsWith('/unknown') || + // Ignore bots. + runningOnBot || + // Ignore when suppressed by FLUTTER_SUPPRESS_ANALYTICS. + suppressEnvFlag) { + return NoOpAnalytics(); + } + + // Providing an override of the [Analytics] instance is preferred when + // running tests for this function to prevent writing to the filesystem + if (analyticsOverride != null) { + return analyticsOverride; + } + + return Analytics( + tool: DashTool.flutterTool, + flutterChannel: flutterVersion.channel, + flutterVersion: flutterVersion.frameworkVersion, + dartVersion: flutterVersion.dartSdkVersion, + enableAsserts: enableAsserts, + ); +} diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index 742132b908c80..1b63932ce60c7 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart @@ -1017,17 +1017,17 @@ abstract class ResidentHandlers { } Future _takeVmServiceScreenshot(FlutterDevice device, File outputFile) async { - final bool isWebDevice = device.targetPlatform == TargetPlatform.web_javascript; + if (device.targetPlatform != TargetPlatform.web_javascript) { + return false; + } assert(supportsServiceProtocol); return _toggleDebugBanner(device, () async { - final vm_service.Response? response = isWebDevice - ? await device.vmService!.callMethodWrapper('ext.dwds.screenshot') - : await device.vmService!.screenshot(); + final vm_service.Response? response = await device.vmService!.callMethodWrapper('ext.dwds.screenshot'); if (response == null) { throw Exception('Failed to take screenshot'); } - final String data = response.json![isWebDevice ? 'data' : 'screenshot'] as String; + final String data = response.json!['data'] as String; outputFile.writeAsBytesSync(base64.decode(data)); }); } diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index 36cf0c575f4f2..1d99c9a29e450 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -1247,10 +1247,20 @@ abstract class FlutterCommand extends Command { } } + final String? flavor = argParser.options.containsKey('flavor') ? stringArg('flavor') : null; + if (flavor != null) { + if (globals.platform.environment['FLUTTER_APP_FLAVOR'] != null) { + throwToolExit('FLUTTER_APP_FLAVOR is used by the framework and cannot be set in the environment.'); + } + if (dartDefines.any((String define) => define.startsWith('FLUTTER_APP_FLAVOR'))) { + throwToolExit('FLUTTER_APP_FLAVOR is used by the framework and cannot be ' + 'set using --${FlutterOptions.kDartDefinesOption} or --${FlutterOptions.kDartDefineFromFileOption}'); + } + dartDefines.add('FLUTTER_APP_FLAVOR=$flavor'); + } + return BuildInfo(buildMode, - argParser.options.containsKey('flavor') - ? stringArg('flavor') - : null, + flavor, trackWidgetCreation: trackWidgetCreation, frontendServerStarterPath: argParser.options .containsKey(FlutterOptions.kFrontendServerStarterPath) diff --git a/packages/flutter_tools/lib/src/test/flutter_web_platform.dart b/packages/flutter_tools/lib/src/test/flutter_web_platform.dart index ec99e517b066a..6400b7a059304 100644 --- a/packages/flutter_tools/lib/src/test/flutter_web_platform.dart +++ b/packages/flutter_tools/lib/src/test/flutter_web_platform.dart @@ -441,6 +441,14 @@ class FlutterWebPlatform extends PlatformPlugin { if (_closed) { throw StateError('Load called on a closed FlutterWebPlatform'); } + + final String pathFromTest = _fileSystem.path.relative(path, from: _fileSystem.path.join(_root, 'test')); + final Uri suiteUrl = url.resolveUri(_fileSystem.path.toUri('${_fileSystem.path.withoutExtension(pathFromTest)}.html')); + final String relativePath = _fileSystem.path.relative(_fileSystem.path.normalize(path), from: _fileSystem.currentDirectory.path); + if (_logger.isVerbose) { + _logger.printTrace('Loading test suite $relativePath.'); + } + final PoolResource lockResource = await _suiteLock.request(); final Runtime browser = platform.runtime; @@ -455,17 +463,23 @@ class FlutterWebPlatform extends PlatformPlugin { throw StateError('Load called on a closed FlutterWebPlatform'); } - final String pathFromTest = _fileSystem.path.relative(path, from: _fileSystem.path.join(_root, 'test')); - final Uri suiteUrl = url.resolveUri(_fileSystem.path.toUri('${_fileSystem.path.withoutExtension(pathFromTest)}.html')); - final String relativePath = _fileSystem.path.relative(_fileSystem.path.normalize(path), from: _fileSystem.currentDirectory.path); + if (_logger.isVerbose) { + _logger.printTrace('Running test suite $relativePath.'); + } + final RunnerSuite suite = await _browserManager!.load(relativePath, suiteUrl, suiteConfig, message, onDone: () async { await _browserManager!.close(); _browserManager = null; lockResource.release(); + if (_logger.isVerbose) { + _logger.printTrace('Test suite $relativePath finished.'); + } }); + if (_closed) { throw StateError('Load called on a closed FlutterWebPlatform'); } + return suite; } diff --git a/packages/flutter_tools/lib/src/test/test_compiler.dart b/packages/flutter_tools/lib/src/test/test_compiler.dart index 600478faa3e23..1433a7150c260 100644 --- a/packages/flutter_tools/lib/src/test/test_compiler.dart +++ b/packages/flutter_tools/lib/src/test/test_compiler.dart @@ -20,6 +20,7 @@ import '../linux/native_assets.dart'; import '../macos/native_assets.dart'; import '../native_assets.dart'; import '../project.dart'; +import '../windows/native_assets.dart'; import 'test_time_recorder.dart'; /// A request to the [TestCompiler] for recompilation. @@ -195,6 +196,14 @@ class TestCompiler { fileSystem: globals.fs, buildRunner: buildRunner, ); + } else if (globals.platform.isWindows) { + (nativeAssetsYaml, _) = await buildNativeAssetsWindows( + buildMode: buildInfo.mode, + projectUri: projectUri, + flutterTester: true, + fileSystem: globals.fs, + buildRunner: buildRunner, + ); } else { await ensureNoNativeAssetsOrOsIsSupported( projectUri, diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart index 78a5b92bd7787..60874eccd4d78 100644 --- a/packages/flutter_tools/lib/src/vmservice.dart +++ b/packages/flutter_tools/lib/src/vmservice.dart @@ -28,7 +28,6 @@ const String kFlushUIThreadTasksMethod = '_flutter.flushUIThreadTasks'; const String kRunInViewMethod = '_flutter.runInView'; const String kListViewsMethod = '_flutter.listViews'; const String kScreenshotSkpMethod = '_flutter.screenshotSkp'; -const String kScreenshotMethod = '_flutter.screenshot'; const String kRenderFrameWithRasterStatsMethod = '_flutter.renderFrameWithRasterStats'; const String kReloadAssetFonts = '_flutter.reloadAssetFonts'; @@ -1054,10 +1053,6 @@ class FlutterVmService { ); } - Future screenshot() { - return _checkedCallServiceExtension(kScreenshotMethod); - } - Future screenshotSkp() { return _checkedCallServiceExtension(kScreenshotSkpMethod); } diff --git a/packages/flutter_tools/lib/src/web/chrome.dart b/packages/flutter_tools/lib/src/web/chrome.dart index 3d2ed0be9b50b..f35a6634a2d6f 100644 --- a/packages/flutter_tools/lib/src/web/chrome.dart +++ b/packages/flutter_tools/lib/src/web/chrome.dart @@ -225,10 +225,10 @@ class ChromiumLauncher { url, ]; - final Process? process = await _spawnChromiumProcess(args, chromeExecutable); + final Process process = await _spawnChromiumProcess(args, chromeExecutable); // When the process exits, copy the user settings back to the provided data-dir. - if (process != null && cacheDir != null) { + if (cacheDir != null) { unawaited(process.exitCode.whenComplete(() { _cacheUserSessionInformation(userDataDir, cacheDir); // cleanup temp dir @@ -245,10 +245,11 @@ class ChromiumLauncher { url: url, process: process, chromiumLauncher: this, + logger: _logger, ), skipCheck); } - Future _spawnChromiumProcess(List args, String chromeExecutable) async { + Future _spawnChromiumProcess(List args, String chromeExecutable) async { if (_operatingSystemUtils.hostPlatform == HostPlatform.darwin_arm64) { final ProcessResult result = _processManager.runSync(['file', chromeExecutable]); // Check if ARM Chrome is installed. @@ -469,25 +470,58 @@ class Chromium { this.debugPort, this.chromeConnection, { this.url, - Process? process, + required Process process, required ChromiumLauncher chromiumLauncher, + required Logger logger, }) : _process = process, - _chromiumLauncher = chromiumLauncher; + _chromiumLauncher = chromiumLauncher, + _logger = logger; final String? url; final int debugPort; - final Process? _process; + final Process _process; final ChromeConnection chromeConnection; final ChromiumLauncher _chromiumLauncher; + final Logger _logger; - Future get onExit async => _process?.exitCode; + /// Resolves to browser's main process' exit code, when the browser exits. + Future get onExit async => _process.exitCode; + + /// The main Chromium process that represents this instance of Chromium. + /// + /// Killing this process should result in the browser exiting. + @visibleForTesting + Process get process => _process; + /// Closes all connections to the browser and asks the browser to exit. Future close() async { + if (_logger.isVerbose) { + _logger.printTrace('Shutting down Chromium.'); + } if (_chromiumLauncher.hasChromeInstance) { _chromiumLauncher.currentCompleter = Completer(); } chromeConnection.close(); - _process?.kill(); - await _process?.exitCode; + + // Try to exit Chromium nicely using SIGTERM, before exiting it rudely using + // SIGKILL. Wait no longer than 5 seconds for Chromium to exit before + // falling back to SIGKILL, and then to a warning message. + ProcessSignal.sigterm.kill(_process); + await _process.exitCode.timeout(const Duration(seconds: 5), onTimeout: () { + _logger.printWarning( + 'Failed to exit Chromium (pid: ${_process.pid}) using SIGTERM. Will try ' + 'sending SIGKILL instead.' + ); + ProcessSignal.sigkill.kill(_process); + return _process.exitCode.timeout(const Duration(seconds: 5), onTimeout: () async { + _logger.printWarning( + 'Failed to exit Chromium (pid: ${_process.pid}) using SIGKILL. Giving ' + 'up. Will continue, assuming Chromium has exited successfully, but ' + 'it is possible that this left a dangling Chromium process running ' + 'on the system.' + ); + return 0; + }); + }); } } diff --git a/packages/flutter_tools/lib/src/web/file_generators/wasm_bootstrap.dart b/packages/flutter_tools/lib/src/web/file_generators/wasm_bootstrap.dart index 0d1a755c0f2c2..caafc3d358146 100644 --- a/packages/flutter_tools/lib/src/web/file_generators/wasm_bootstrap.dart +++ b/packages/flutter_tools/lib/src/web/file_generators/wasm_bootstrap.dart @@ -46,7 +46,8 @@ String generateImports(bool isSkwasm) { const skwasmInstance = await skwasm(); window._flutter_skwasmInstance = skwasmInstance; resolve({ - 'skwasm': skwasmInstance.asm ?? skwasmInstance.wasmExports, + 'skwasm': skwasmInstance.wasmExports, + 'skwasmWrapper': skwasmInstance, 'ffi': { 'memory': skwasmInstance.wasmMemory, } diff --git a/packages/flutter_tools/lib/src/windows/build_windows.dart b/packages/flutter_tools/lib/src/windows/build_windows.dart index 5d88dddef5fed..dddc0d424d2bf 100644 --- a/packages/flutter_tools/lib/src/windows/build_windows.dart +++ b/packages/flutter_tools/lib/src/windows/build_windows.dart @@ -18,6 +18,7 @@ import '../convert.dart'; import '../flutter_plugins.dart'; import '../globals.dart' as globals; import '../migrations/cmake_custom_command_migration.dart'; +import '../migrations/cmake_native_assets_migration.dart'; import 'migrations/build_architecture_migration.dart'; import 'migrations/show_window_migration.dart'; import 'migrations/version_migration.dart'; @@ -61,6 +62,7 @@ Future buildWindows(WindowsProject windowsProject, BuildInfo buildInfo, { final List migrators = [ CmakeCustomCommandMigration(windowsProject, globals.logger), + CmakeNativeAssetsMigration(windowsProject, 'windows', globals.logger), VersionMigration(windowsProject, globals.logger), ShowWindowMigration(windowsProject, globals.logger), BuildArchitectureMigration(windowsProject, buildDirectory, globals.logger), diff --git a/packages/flutter_tools/lib/src/windows/native_assets.dart b/packages/flutter_tools/lib/src/windows/native_assets.dart new file mode 100644 index 0000000000000..c5f5835d0084f --- /dev/null +++ b/packages/flutter_tools/lib/src/windows/native_assets.dart @@ -0,0 +1,91 @@ +// Copyright 2014 The Flutter 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:native_assets_cli/native_assets_cli.dart' hide BuildMode; + +import '../base/file_system.dart'; +import '../build_info.dart'; +import '../globals.dart' as globals; +import '../native_assets.dart'; +import 'visual_studio.dart'; + +/// Dry run the native builds. +/// +/// This does not build native assets, it only simulates what the final paths +/// of all assets will be so that this can be embedded in the kernel file. +Future dryRunNativeAssetsWindows({ + required NativeAssetsBuildRunner buildRunner, + required Uri projectUri, + bool flutterTester = false, + required FileSystem fileSystem, +}) { + return dryRunNativeAssetsSingleArchitecture( + buildRunner: buildRunner, + projectUri: projectUri, + flutterTester: flutterTester, + fileSystem: fileSystem, + os: OS.windows, + ); +} + +Future> dryRunNativeAssetsWindowsInternal( + FileSystem fileSystem, + Uri projectUri, + bool flutterTester, + NativeAssetsBuildRunner buildRunner, +) { + return dryRunNativeAssetsSingleArchitectureInternal( + fileSystem, + projectUri, + flutterTester, + buildRunner, + OS.windows, + ); +} + +Future<(Uri? nativeAssetsYaml, List dependencies)> + buildNativeAssetsWindows({ + required NativeAssetsBuildRunner buildRunner, + TargetPlatform? targetPlatform, + required Uri projectUri, + required BuildMode buildMode, + bool flutterTester = false, + Uri? yamlParentDirectory, + required FileSystem fileSystem, +}) { + return buildNativeAssetsSingleArchitecture( + buildRunner: buildRunner, + targetPlatform: targetPlatform, + projectUri: projectUri, + buildMode: buildMode, + flutterTester: flutterTester, + yamlParentDirectory: yamlParentDirectory, + fileSystem: fileSystem, + ); +} + + +Future cCompilerConfigWindows() async { + final VisualStudio visualStudio = VisualStudio( + fileSystem: globals.fs, + platform: globals.platform, + logger: globals.logger, + processManager: globals.processManager, + ); + + return CCompilerConfig( + cc: _toOptionalFileUri(visualStudio.clPath), + ld: _toOptionalFileUri(visualStudio.linkPath), + ar: _toOptionalFileUri(visualStudio.libPath), + envScript: _toOptionalFileUri(visualStudio.vcvarsPath), + envScriptArgs: [], + ); +} + +Uri? _toOptionalFileUri(String? string) { + if (string == null) { + return null; + } + return Uri.file(string); +} diff --git a/packages/flutter_tools/lib/src/windows/visual_studio.dart b/packages/flutter_tools/lib/src/windows/visual_studio.dart index e9c39aa2fa4db..5251450a81b4e 100644 --- a/packages/flutter_tools/lib/src/windows/visual_studio.dart +++ b/packages/flutter_tools/lib/src/windows/visual_studio.dart @@ -184,6 +184,60 @@ class VisualStudio { } } + /// The path to cl.exe, or null if no Visual Studio installation has + /// the components necessary to build. + String? get clPath { + return _getMsvcBinPath('cl.exe'); + } + + /// The path to lib.exe, or null if no Visual Studio installation has + /// the components necessary to build. + String? get libPath { + return _getMsvcBinPath('lib.exe'); + } + + /// The path to link.exe, or null if no Visual Studio installation has + /// the components necessary to build. + String? get linkPath { + return _getMsvcBinPath('link.exe'); + } + + String? _getMsvcBinPath(String executable) { + final VswhereDetails? details = _bestVisualStudioDetails; + if (details == null || !details.isUsable || details.installationPath == null || details.msvcVersion == null) { + return null; + } + + return _fileSystem.path.joinAll([ + details.installationPath!, + 'VC', + 'Tools', + 'MSVC', + details.msvcVersion!, + 'bin', + 'Hostx64', + 'x64', + executable, + ]); + } + + /// The path to vcvars64.exe, or null if no Visual Studio installation has + /// the components necessary to build. + String? get vcvarsPath { + final VswhereDetails? details = _bestVisualStudioDetails; + if (details == null || !details.isUsable || details.installationPath == null) { + return null; + } + + return _fileSystem.path.joinAll([ + details.installationPath!, + 'VC', + 'Auxiliary', + 'Build', + 'vcvars64.bat', + ]); + } + /// The major version of the Visual Studio install, as an integer. int? get _majorVersion => fullVersion != null ? int.tryParse(fullVersion!.split('.')[0]) : null; @@ -301,7 +355,12 @@ class VisualStudio { if (whereResult.exitCode == 0) { final List>? installations = _tryDecodeVswhereJson(whereResult.stdout); if (installations != null && installations.isNotEmpty) { - return VswhereDetails.fromJson(validateRequirements, installations[0]); + final String? msvcVersion = _findMsvcVersion(installations); + return VswhereDetails.fromJson( + validateRequirements, + installations[0], + msvcVersion, + ); } } } on ArgumentError { @@ -312,6 +371,28 @@ class VisualStudio { return null; } + String? _findMsvcVersion(List> installations) { + final String? installationPath = installations[0]['installationPath'] as String?; + String? msvcVersion; + if (installationPath != null) { + final Directory installationDir = _fileSystem.directory(installationPath); + final Directory msvcDir = installationDir + .childDirectory('VC') + .childDirectory('Tools') + .childDirectory('MSVC'); + if (msvcDir.existsSync()) { + final Iterable msvcVersionDirs = msvcDir.listSync().whereType(); + if (msvcVersionDirs.isEmpty) { + return null; + } + msvcVersion = msvcVersionDirs.last.uri.pathSegments + .where((String e) => e.isNotEmpty) + .last; + } + } + return msvcVersion; + } + List>? _tryDecodeVswhereJson(String vswhereJson) { List? result; FormatException? originalError; @@ -443,12 +524,14 @@ class VswhereDetails { required this.isRebootRequired, required this.isPrerelease, required this.catalogDisplayVersion, + required this.msvcVersion, }); /// Create a `VswhereDetails` from the JSON output of vswhere.exe. factory VswhereDetails.fromJson( bool meetsRequirements, - Map details + Map details, + String? msvcVersion, ) { final Map? catalog = details['catalog'] as Map?; @@ -467,6 +550,8 @@ class VswhereDetails { // contain replacement characters. displayName: details['displayName'] as String?, catalogDisplayVersion: catalog == null ? null : catalog['productDisplayVersion'] as String?, + + msvcVersion: msvcVersion, ); } @@ -511,6 +596,9 @@ class VswhereDetails { /// The user-friendly version. final String? catalogDisplayVersion; + /// The MSVC versions. + final String? msvcVersion; + /// Checks if the Visual Studio installation can be used by Flutter. /// /// Returns false if the installation has issues the user must resolve. diff --git a/packages/flutter_tools/pubspec.yaml b/packages/flutter_tools/pubspec.yaml index 4a2e14dd4dfa8..7ff86a1c54f05 100644 --- a/packages/flutter_tools/pubspec.yaml +++ b/packages/flutter_tools/pubspec.yaml @@ -28,7 +28,7 @@ dependencies: fake_async: 1.3.1 stack_trace: 1.11.1 usage: 4.1.1 - webdriver: 3.0.2 + webdriver: 3.0.3 webkit_inspection_protocol: 1.2.1 xml: 6.4.2 yaml: 3.1.2 @@ -48,12 +48,12 @@ dependencies: http_multi_server: 3.2.1 convert: 3.1.1 async: 2.11.0 - unified_analytics: 4.0.0 + unified_analytics: 4.0.1 - cli_config: 0.1.1 + cli_config: 0.1.2 graphs: 2.3.1 - native_assets_builder: 0.2.3 - native_assets_cli: 0.2.0 + native_assets_builder: 0.3.0 + native_assets_cli: 0.3.0 # We depend on very specific internal implementation details of the # 'test' package, which change between versions, so when upgrading @@ -112,4 +112,4 @@ dartdoc: # Exclude this package from the hosted API docs. nodoc: true -# PUBSPEC CHECKSUM: 887b +# PUBSPEC CHECKSUM: 177d diff --git a/packages/flutter_tools/templates/app_shared/windows.tmpl/CMakeLists.txt.tmpl b/packages/flutter_tools/templates/app_shared/windows.tmpl/CMakeLists.txt.tmpl index 78f98b83d572f..0c89cfcd82feb 100644 --- a/packages/flutter_tools/templates/app_shared/windows.tmpl/CMakeLists.txt.tmpl +++ b/packages/flutter_tools/templates/app_shared/windows.tmpl/CMakeLists.txt.tmpl @@ -91,6 +91,12 @@ if(PLUGIN_BUNDLED_LIBRARIES) COMPONENT Runtime) endif() +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") diff --git a/packages/flutter_tools/templates/package_ffi/pubspec.yaml.tmpl b/packages/flutter_tools/templates/package_ffi/pubspec.yaml.tmpl index 8fa5f3ac67ad0..d9ef78c86db8a 100644 --- a/packages/flutter_tools/templates/package_ffi/pubspec.yaml.tmpl +++ b/packages/flutter_tools/templates/package_ffi/pubspec.yaml.tmpl @@ -9,8 +9,8 @@ environment: dependencies: cli_config: ^0.1.1 logging: ^1.1.1 - native_assets_cli: ^0.2.0 - native_toolchain_c: ^0.2.0 + native_assets_cli: ^0.3.0 + native_toolchain_c: ^0.3.0 dev_dependencies: ffi: ^2.0.2 diff --git a/packages/flutter_tools/test/commands.shard/hermetic/config_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/config_test.dart index d3e86de9695e1..4f98a5b37020e 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/config_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/config_test.dart @@ -12,6 +12,7 @@ import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/commands/config.dart'; +import 'package:flutter_tools/src/features.dart'; import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/version.dart'; @@ -48,6 +49,23 @@ void main() { } group('config', () { + testUsingContext('prints all settings with --list', () async { + final ConfigCommand configCommand = ConfigCommand(); + final CommandRunner commandRunner = createTestCommandRunner(configCommand); + await commandRunner.run(['config', '--list']); + expect( + testLogger.statusText, + 'All Settings:\n' + '${allFeatures + .where((Feature e) => e.configSetting != null) + .map((Feature e) => ' ${e.configSetting}: (Not set)') + .join('\n')}' + '\n\n', + ); + }, overrides: { + Usage: () => testUsage, + }); + testUsingContext('throws error on excess arguments', () { final ConfigCommand configCommand = ConfigCommand(); final CommandRunner commandRunner = createTestCommandRunner(configCommand); @@ -196,6 +214,7 @@ void main() { await commandRunner.run([ 'config', + '--list' ]); expect( @@ -270,20 +289,21 @@ void main() { Usage: () => testUsage, }); - testUsingContext('analytics reported disabled when suppressed', () async { + testUsingContext('analytics reported with help usages', () async { final ConfigCommand configCommand = ConfigCommand(); - final CommandRunner commandRunner = createTestCommandRunner(configCommand); + createTestCommandRunner(configCommand); testUsage.suppressAnalytics = true; - - await commandRunner.run([ - 'config', - ]); - expect( - testLogger.statusText, + configCommand.usage, containsIgnoringWhitespace('Analytics reporting is currently disabled'), ); + + testUsage.suppressAnalytics = false; + expect( + configCommand.usage, + containsIgnoringWhitespace('Analytics reporting is currently enabled'), + ); }, overrides: { Usage: () => testUsage, }); diff --git a/packages/flutter_tools/test/commands.shard/hermetic/screenshot_command_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/screenshot_command_test.dart index 42954dc440a40..01725cc991394 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/screenshot_command_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/screenshot_command_test.dart @@ -31,11 +31,6 @@ void main() { .run(['screenshot', '--type=skia', '--vm-service-url=http://localhost:8181']), throwsA(isException.having((Exception exception) => exception.toString(), 'message', contains('dummy'))), ); - - await expectLater(() => createTestCommandRunner(ScreenshotCommand(fs: MemoryFileSystem.test())) - .run(['screenshot', '--type=rasterizer', '--vm-service-url=http://localhost:8181']), - throwsA(isException.having((Exception exception) => exception.toString(), 'message', contains('dummy'))), - ); }); @@ -44,11 +39,6 @@ void main() { .run(['screenshot', '--type=skia']), throwsToolExit(message: 'VM Service URI must be specified for screenshot type skia') ); - - await expectLater(() => createTestCommandRunner(ScreenshotCommand(fs: MemoryFileSystem.test())) - .run(['screenshot', '--type=rasterizer',]), - throwsToolExit(message: 'VM Service URI must be specified for screenshot type rasterizer'), - ); }); testUsingContext('device screenshots require device', () async { diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart index a736b2b3b9a71..574f389fd62b3 100644 --- a/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart +++ b/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart @@ -36,14 +36,7 @@ const List _kDart2WasmLinuxArgs = [ 'Artifact.dart2wasmSnapshot.TargetPlatform.web_javascript', '--packages=.dart_tool/package_config.json', '--dart-sdk=Artifact.engineDartSdkPath.TargetPlatform.web_javascript', - '--multi-root-scheme', - 'org-dartlang-sdk', - '--multi-root', - 'HostArtifact.flutterWebSdk', - '--multi-root', - _kDartSdkRoot, - '--libraries-spec', - 'HostArtifact.flutterWebLibrariesJson', + '--platform=HostArtifact.webPlatformKernelFolder/dart2wasm_platform.dill', ]; const List _kWasmOptLinuxArgrs = [ @@ -58,10 +51,6 @@ const List _kWasmOptLinuxArgrs = [ '--type-merging', ]; -/// The result of calling `.parent` on a Memory directory pointing to -/// `'Artifact.engineDartSdkPath.TargetPlatform.web_javascript'`. -const String _kDartSdkRoot = '.'; - void main() { late Testbed testbed; late Environment environment; diff --git a/packages/flutter_tools/test/general.shard/fake_native_assets_build_runner.dart b/packages/flutter_tools/test/general.shard/fake_native_assets_build_runner.dart index bcdd74c2d8b52..bd4f99042effd 100644 --- a/packages/flutter_tools/test/general.shard/fake_native_assets_build_runner.dart +++ b/packages/flutter_tools/test/general.shard/fake_native_assets_build_runner.dart @@ -49,7 +49,7 @@ class FakeNativeAssetsBuildRunner implements NativeAssetsBuildRunner { Future dryRun({ required bool includeParentEnvironment, required LinkModePreference linkModePreference, - required OS targetOs, + required OS targetOS, required Uri workingDirectory, }) async { dryRunInvocations++; diff --git a/packages/flutter_tools/test/general.shard/ios/ios_device_start_prebuilt_test.dart b/packages/flutter_tools/test/general.shard/ios/ios_device_start_prebuilt_test.dart index 37edf3ebe38ff..90f834081b269 100644 --- a/packages/flutter_tools/test/general.shard/ios/ios_device_start_prebuilt_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/ios_device_start_prebuilt_test.dart @@ -213,7 +213,7 @@ void main() { completer.complete(); expect(secondLaunchResult.started, true); expect(secondLaunchResult.hasVmService, true); - expect(await device.stopApp(iosApp), false); + expect(await device.stopApp(iosApp), true); }); testWithoutContext('IOSDevice.startApp launches in debug mode via log reading on [ + 'Dry running native assets for ios.', + 'Dry running native assets for ios done.', + ]), + ); expect( nativeAssetsYaml, projectUri.resolve('build/native_assets/ios/native_assets.yaml'), @@ -259,13 +266,20 @@ void main() { Asset( id: 'package:bar/bar.dart', linkMode: LinkMode.dynamic, - target: native_assets_cli.Target.macOSArm64, + target: native_assets_cli.Target.iOSArm64, path: AssetAbsolutePath(Uri.file('bar.dylib')), ), ], ), ), ); + expect( + (globals.logger as BufferLogger).traceText, + stringContainsInOrder([ + 'Building native assets for [ios_arm64] debug.', + 'Building native assets for [ios_arm64] done.', + ]), + ); expect( environment.buildDir.childFile('native_assets.yaml'), exists, diff --git a/packages/flutter_tools/test/general.shard/linux/native_assets_test.dart b/packages/flutter_tools/test/general.shard/linux/native_assets_test.dart index 89797079fd276..19b5ae7016fd0 100644 --- a/packages/flutter_tools/test/general.shard/linux/native_assets_test.dart +++ b/packages/flutter_tools/test/general.shard/linux/native_assets_test.dart @@ -180,6 +180,13 @@ void main() { ), ), ); + expect( + (globals.logger as BufferLogger).traceText, + stringContainsInOrder([ + 'Dry running native assets for linux.', + 'Dry running native assets for linux done.', + ]), + ); expect( nativeAssetsYaml, projectUri.resolve('build/native_assets/linux/native_assets.yaml'), @@ -222,6 +229,7 @@ void main() { await packageConfig.parent.create(); await packageConfig.create(); final (Uri? nativeAssetsYaml, _) = await buildNativeAssetsLinux( + targetPlatform: TargetPlatform.linux_x64, projectUri: projectUri, buildMode: BuildMode.debug, fileSystem: fileSystem, @@ -257,16 +265,14 @@ void main() { FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true), ProcessManager: () => FakeProcessManager.empty(), }, () async { - if (const LocalPlatform().isWindows) { - return; // Backslashes in commands, but we will never run these commands on Windows. - } - final File packageConfig = environment.projectDir.childFile('.dart_tool/package_config.json'); + final File packageConfig = environment.projectDir.childDirectory('.dart_tool').childFile('package_config.json'); await packageConfig.parent.create(); await packageConfig.create(); final File dylibAfterCompiling = fileSystem.file('libbar.so'); // The mock doesn't create the file, so create it here. await dylibAfterCompiling.create(); final (Uri? nativeAssetsYaml, _) = await buildNativeAssetsLinux( + targetPlatform: TargetPlatform.linux_x64, projectUri: projectUri, buildMode: BuildMode.debug, fileSystem: fileSystem, @@ -287,6 +293,13 @@ void main() { ), ), ); + expect( + (globals.logger as BufferLogger).traceText, + stringContainsInOrder([ + 'Building native assets for linux_x64 debug.', + 'Building native assets for linux_x64 done.', + ]), + ); expect( nativeAssetsYaml, projectUri.resolve('build/native_assets/linux/native_assets.yaml'), @@ -297,7 +310,7 @@ void main() { 'package:bar/bar.dart', if (flutterTester) // Tests run on host system, so the have the full path on the system. - '- ${projectUri.resolve('/build/native_assets/linux/libbar.so').toFilePath()}' + '- ${projectUri.resolve('build/native_assets/linux/libbar.so').toFilePath()}' else // Apps are a bundle with the dylibs on their dlopen path. '- libbar.so', @@ -365,7 +378,6 @@ void main() { FileSystem: () => fileSystem, }, () async { if (!const LocalPlatform().isLinux) { - // TODO(dacoharkes): Implement other OSes. https://github.com/flutter/flutter/issues/129757 return; } diff --git a/packages/flutter_tools/test/general.shard/macos/native_assets_test.dart b/packages/flutter_tools/test/general.shard/macos/native_assets_test.dart index 07cdd2bbd3742..877521bc1077b 100644 --- a/packages/flutter_tools/test/general.shard/macos/native_assets_test.dart +++ b/packages/flutter_tools/test/general.shard/macos/native_assets_test.dart @@ -161,6 +161,13 @@ void main() { ), ), ); + expect( + (globals.logger as BufferLogger).traceText, + stringContainsInOrder([ + 'Dry running native assets for macos.', + 'Dry running native assets for macos done.', + ]), + ); expect( nativeAssetsYaml, projectUri.resolve('build/native_assets/macos/native_assets.yaml'), @@ -291,6 +298,13 @@ void main() { ), ), ); + expect( + (globals.logger as BufferLogger).traceText, + stringContainsInOrder([ + 'Building native assets for [macos_arm64] debug.', + 'Building native assets for [macos_arm64] done.', + ]), + ); expect( nativeAssetsYaml, projectUri.resolve('build/native_assets/macos/native_assets.yaml'), @@ -301,7 +315,7 @@ void main() { 'package:bar/bar.dart', if (flutterTester) // Tests run on host system, so the have the full path on the system. - '- ${projectUri.resolve('/build/native_assets/macos/bar.dylib').toFilePath()}' + '- ${projectUri.resolve('build/native_assets/macos/bar.dylib').toFilePath()}' else // Apps are a bundle with the dylibs on their dlopen path. '- bar.dylib', @@ -370,7 +384,6 @@ InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault ), }, () async { if (!const LocalPlatform().isMacOS) { - // TODO(dacoharkes): Implement other OSes. https://github.com/flutter/flutter/issues/129757 return; } diff --git a/packages/flutter_tools/test/general.shard/migrations/cmake_project_migration_test.dart b/packages/flutter_tools/test/general.shard/migrations/cmake_project_migration_test.dart index 8689febb15ae8..6ebbfa9bc2705 100644 --- a/packages/flutter_tools/test/general.shard/migrations/cmake_project_migration_test.dart +++ b/packages/flutter_tools/test/general.shard/migrations/cmake_project_migration_test.dart @@ -230,9 +230,9 @@ install(DIRECTORY "${NATIVE_ASSETS_DIR}" expect(testLogger.statusText, isEmpty); }); - // TODO(dacoharkes): Add test for Windows when adding Windows support. https://github.com/flutter/flutter/issues/129757 - testWithoutContext('is migrated to copy native assets', () { - managedCmakeFile.writeAsStringSync(r''' + for (final String os in ['linux', 'windows']) { + testWithoutContext('is migrated to copy native assets', () { + managedCmakeFile.writeAsStringSync(r''' foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) install(FILES "${bundled_library}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" @@ -249,38 +249,40 @@ install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) '''); - final CmakeNativeAssetsMigration cmakeProjectMigration = CmakeNativeAssetsMigration( - mockCmakeProject, - 'linux', - testLogger, - ); - cmakeProjectMigration.migrate(); - - expect(managedCmakeFile.readAsStringSync(), r''' -foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) - install(FILES "${bundled_library}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + final CmakeNativeAssetsMigration cmakeProjectMigration = CmakeNativeAssetsMigration( + mockCmakeProject, + os, + testLogger, + ); + cmakeProjectMigration.migrate(); + + expect(managedCmakeFile.readAsStringSync(), ''' +foreach(bundled_library \${PLUGIN_BUNDLED_LIBRARIES}) + install(FILES "\${bundled_library}" + DESTINATION "\${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endforeach(bundled_library) # Copy the native assets provided by the build.dart from all packages. -set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") -install(DIRECTORY "${NATIVE_ASSETS_DIR}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) +set(NATIVE_ASSETS_DIR "\${PROJECT_BUILD_DIR}native_assets/$os/") +install(DIRECTORY "\${NATIVE_ASSETS_DIR}" + DESTINATION "\${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + file(REMOVE_RECURSE \\"\${INSTALL_BUNDLE_DATA_DIR}/\${FLUTTER_ASSET_DIR_NAME}\\") " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) +install(DIRECTORY "\${PROJECT_BUILD_DIR}/\${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "\${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) '''); - expect(testLogger.statusText, contains('CMake missing install() NATIVE_ASSETS_DIR command, updating.')); - }); + expect(testLogger.statusText, + contains('CMake missing install() NATIVE_ASSETS_DIR command, updating.')); + }); + } }); }); } diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart index 4fc88ae771b6a..f7b63a0f9364d 100644 --- a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart @@ -39,6 +39,7 @@ import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; import '../src/common.dart'; import '../src/context.dart'; +import '../src/fake_process_manager.dart'; import '../src/fake_vm_services.dart'; const List kAttachLogExpectations = @@ -620,8 +621,9 @@ void main() { ]); setupMocks(); final TestChromiumLauncher chromiumLauncher = TestChromiumLauncher(); + final FakeProcess process = FakeProcess(); final Chromium chrome = - Chromium(1, chromeConnection, chromiumLauncher: chromiumLauncher); + Chromium(1, chromeConnection, chromiumLauncher: chromiumLauncher, process: process, logger: logger); chromiumLauncher.setInstance(chrome); flutterDevice.device = GoogleChromeDevice( @@ -687,8 +689,9 @@ void main() { ]); setupMocks(); final TestChromiumLauncher chromiumLauncher = TestChromiumLauncher(); + final FakeProcess process = FakeProcess(); final Chromium chrome = - Chromium(1, chromeConnection, chromiumLauncher: chromiumLauncher); + Chromium(1, chromeConnection, chromiumLauncher: chromiumLauncher, process: process, logger: logger); chromiumLauncher.setInstance(chrome); flutterDevice.device = GoogleChromeDevice( @@ -1025,8 +1028,9 @@ void main() { setupMocks(); final FakeChromeConnection chromeConnection = FakeChromeConnection(); final TestChromiumLauncher chromiumLauncher = TestChromiumLauncher(); + final FakeProcess process = FakeProcess(); final Chromium chrome = - Chromium(1, chromeConnection, chromiumLauncher: chromiumLauncher); + Chromium(1, chromeConnection, chromiumLauncher: chromiumLauncher, process: process, logger: logger); chromiumLauncher.setInstance(chrome); flutterDevice.device = GoogleChromeDevice( diff --git a/packages/flutter_tools/test/general.shard/runner/flutter_command_test.dart b/packages/flutter_tools/test/general.shard/runner/flutter_command_test.dart index 810c8ef3379a6..9f6d9c5e2c17e 100644 --- a/packages/flutter_tools/test/general.shard/runner/flutter_command_test.dart +++ b/packages/flutter_tools/test/general.shard/runner/flutter_command_test.dart @@ -11,11 +11,14 @@ import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/error_handling_io.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/io.dart'; +import 'package:flutter_tools/src/base/logger.dart'; +import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/signals.dart'; import 'package:flutter_tools/src/base/time.dart'; import 'package:flutter_tools/src/base/user_messages.dart'; import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/cache.dart'; +import 'package:flutter_tools/src/commands/run.dart'; import 'package:flutter_tools/src/dart/pub.dart'; import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/globals.dart' as globals; @@ -700,6 +703,67 @@ void main() { expect(testLogger.statusText, contains(UserMessages().flutterSpecifyDevice)); }); }); + + group('--flavor', () { + late _TestDeviceManager testDeviceManager; + late Logger logger; + late FileSystem fileSystem; + + setUp(() { + logger = BufferLogger.test(); + testDeviceManager = _TestDeviceManager(logger: logger); + fileSystem = MemoryFileSystem.test(); + }); + + testUsingContext("tool exits when FLUTTER_APP_FLAVOR is already set in user's environment", () async { + fileSystem.file('lib/main.dart').createSync(recursive: true); + fileSystem.file('pubspec.yaml').createSync(); + fileSystem.file('.packages').createSync(); + + final FakeDevice device = FakeDevice('name', 'id'); + testDeviceManager.devices = [device]; + final _TestRunCommandThatOnlyValidates command = _TestRunCommandThatOnlyValidates(); + final CommandRunner runner = createTestCommandRunner(command); + + expect(runner.run(['run', '--no-pub', '--no-hot', '--flavor=strawberry']), + throwsToolExit(message: 'FLUTTER_APP_FLAVOR is used by the framework and cannot be set in the environment.')); + + }, overrides: { + DeviceManager: () => testDeviceManager, + Platform: () => FakePlatform( + environment: { + 'FLUTTER_APP_FLAVOR': 'I was already set' + } + ), + Cache: () => Cache.test(processManager: FakeProcessManager.any()), + FileSystem: () => fileSystem, + ProcessManager: () => FakeProcessManager.any(), + }); + + testUsingContext('tool exits when FLUTTER_APP_FLAVOR is set in --dart-define or --dart-define-from-file', () async { + fileSystem.file('lib/main.dart').createSync(recursive: true); + fileSystem.file('pubspec.yaml').createSync(); + fileSystem.file('.packages').createSync(); + fileSystem.file('config.json')..createSync()..writeAsStringSync('{"FLUTTER_APP_FLAVOR": "strawberry"}'); + + final FakeDevice device = FakeDevice('name', 'id'); + testDeviceManager.devices = [device]; + final _TestRunCommandThatOnlyValidates command = _TestRunCommandThatOnlyValidates(); + final CommandRunner runner = createTestCommandRunner(command); + + expect(runner.run(['run', '--dart-define=FLUTTER_APP_FLAVOR=strawberry', '--no-pub', '--no-hot', '--flavor=strawberry']), + throwsToolExit(message: 'FLUTTER_APP_FLAVOR is used by the framework and cannot be set using --dart-define or --dart-define-from-file')); + + expect(runner.run(['run', '--dart-define-from-file=config.json', '--no-pub', '--no-hot', '--flavor=strawberry']), + throwsToolExit(message: 'FLUTTER_APP_FLAVOR is used by the framework and cannot be set using --dart-define or --dart-define-from-file')); + }, overrides: { + DeviceManager: () => testDeviceManager, + Platform: () => FakePlatform(), + Cache: () => Cache.test(processManager: FakeProcessManager.any()), + FileSystem: () => fileSystem, + ProcessManager: () => FakeProcessManager.any(), + }); + }); }); } @@ -853,3 +917,22 @@ class FakePub extends Fake implements Pub { PubOutputMode outputMode = PubOutputMode.all, }) async { } } + +class _TestDeviceManager extends DeviceManager { + _TestDeviceManager({required super.logger}); + List devices = []; + + @override + List get deviceDiscoverers { + final FakePollingDeviceDiscovery discoverer = FakePollingDeviceDiscovery(); + devices.forEach(discoverer.addDevice); + return [discoverer]; + } +} + +class _TestRunCommandThatOnlyValidates extends RunCommand { + @override + Future runCommand() async { + return FlutterCommandResult.success(); + } +} diff --git a/packages/flutter_tools/test/general.shard/terminal_handler_test.dart b/packages/flutter_tools/test/general.shard/terminal_handler_test.dart index e6a38e5d39ae3..33f615c85ad75 100644 --- a/packages/flutter_tools/test/general.shard/terminal_handler_test.dart +++ b/packages/flutter_tools/test/general.shard/terminal_handler_test.dart @@ -1015,38 +1015,14 @@ void main() { expect(logger.statusText, contains('Screenshot written to flutter_01.png (0kB)')); }); - testWithoutContext('s, can take screenshot on debug device that does not support screenshot', () async { + testWithoutContext('s, will not take screenshot on non-web device without screenshot tooling support', () async { final BufferLogger logger = BufferLogger.test(); final FileSystem fileSystem = MemoryFileSystem.test(); - final TerminalHandler terminalHandler = setUpTerminalHandler([ - listViews, - FakeVmServiceRequest( - method: 'ext.flutter.debugAllowBanner', - args: { - 'isolateId': fakeUnpausedIsolate.id, - 'enabled': 'false', - }, - ), - FakeVmServiceRequest( - method: '_flutter.screenshot', - args: {}, - jsonResponse: { - 'screenshot': base64.encode([1, 2, 3, 4]), - }, - ), - FakeVmServiceRequest( - method: 'ext.flutter.debugAllowBanner', - args: { - 'isolateId': fakeUnpausedIsolate.id, - 'enabled': 'true', - }, - ), - ], logger: logger, fileSystem: fileSystem); + final TerminalHandler terminalHandler = setUpTerminalHandler([], logger: logger, fileSystem: fileSystem); await terminalHandler.processTerminalInput('s'); - expect(logger.statusText, contains('Screenshot written to flutter_01.png (0kB)')); - expect(fileSystem.currentDirectory.childFile('flutter_01.png').readAsBytesSync(), [1, 2, 3, 4]); + expect(logger.statusText, isNot(contains('Screenshot written to'))); }); testWithoutContext('s, can take screenshot on debug web device that does not support screenshot', () async { @@ -1133,66 +1109,6 @@ void main() { expect(fileSystem.currentDirectory.childFile('flutter_01.png'), isNot(exists)); }); - testWithoutContext('s, bails taking screenshot on debug device if debugAllowBanner throws RpcError', () async { - final BufferLogger logger = BufferLogger.test(); - final FileSystem fileSystem = MemoryFileSystem.test(); - final TerminalHandler terminalHandler = setUpTerminalHandler( - [ - listViews, - FakeVmServiceRequest( - method: 'ext.flutter.debugAllowBanner', - args: { - 'isolateId': fakeUnpausedIsolate.id, - 'enabled': 'false', - }, - // Failed response, - errorCode: RPCErrorCodes.kInternalError, - ), - ], - logger: logger, - fileSystem: fileSystem, - ); - - await terminalHandler.processTerminalInput('s'); - - expect(logger.errorText, contains('Error')); - }); - - testWithoutContext('s, bails taking screenshot on debug device if flutter.screenshot throws RpcError, restoring banner', () async { - final BufferLogger logger = BufferLogger.test(); - final FileSystem fileSystem = MemoryFileSystem.test(); - final TerminalHandler terminalHandler = setUpTerminalHandler( - [ - listViews, - FakeVmServiceRequest( - method: 'ext.flutter.debugAllowBanner', - args: { - 'isolateId': fakeUnpausedIsolate.id, - 'enabled': 'false', - }, - ), - const FakeVmServiceRequest( - method: '_flutter.screenshot', - // Failed response, - errorCode: RPCErrorCodes.kInternalError, - ), - FakeVmServiceRequest( - method: 'ext.flutter.debugAllowBanner', - args: { - 'isolateId': fakeUnpausedIsolate.id, - 'enabled': 'true', - }, - ), - ], - logger: logger, - fileSystem: fileSystem, - ); - - await terminalHandler.processTerminalInput('s'); - - expect(logger.errorText, contains('Error')); - }); - testWithoutContext('s, bails taking screenshot on debug device if dwds.screenshot throws RpcError, restoring banner', () async { final BufferLogger logger = BufferLogger.test(); final FileSystem fileSystem = MemoryFileSystem.test(); diff --git a/packages/flutter_tools/test/general.shard/unified_analytics_test.dart b/packages/flutter_tools/test/general.shard/unified_analytics_test.dart new file mode 100644 index 0000000000000..f52a977622aef --- /dev/null +++ b/packages/flutter_tools/test/general.shard/unified_analytics_test.dart @@ -0,0 +1,139 @@ +// Copyright 2014 The Flutter 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:file/memory.dart'; +import 'package:flutter_tools/src/base/file_system.dart'; +import 'package:flutter_tools/src/reporting/unified_analytics.dart'; +import 'package:unified_analytics/src/enums.dart'; +import 'package:unified_analytics/unified_analytics.dart'; + +import '../src/common.dart'; +import '../src/fakes.dart'; + +void main() { + const String userBranch = 'abc123'; + const String homeDirectoryName = 'home'; + const DashTool tool = DashTool.flutterTool; + + late FileSystem fs; + late Directory home; + late FakeAnalytics analyticsOverride; + + setUp(() { + fs = MemoryFileSystem.test(); + home = fs.directory(homeDirectoryName); + + // Prepare the tests by "onboarding" the tool into the package + // by invoking the [clientShowedMessage] method for the provided + // [tool] + final FakeAnalytics initialAnalytics = FakeAnalytics( + tool: tool, + homeDirectory: home, + dartVersion: '3.0.0', + platform: DevicePlatform.macos, + fs: fs, + surveyHandler: SurveyHandler( + homeDirectory: home, + fs: fs, + ), + ); + initialAnalytics.clientShowedMessage(); + + analyticsOverride = FakeAnalytics( + tool: tool, + homeDirectory: home, + dartVersion: '3.0.0', + platform: DevicePlatform.macos, + fs: fs, + surveyHandler: SurveyHandler( + homeDirectory: home, + fs: fs, + ), + ); + }); + + group('Unit testing getAnalytics', () { + testWithoutContext('Successfully creates the instance for standard branch', () { + final Analytics analytics = getAnalytics( + runningOnBot: false, + flutterVersion: FakeFlutterVersion(), + environment: const {}, + analyticsOverride: analyticsOverride, + ); + + expect(analytics.clientId, isNot(NoOpAnalytics.staticClientId), + reason: 'The CLIENT ID should be a randomly generated id'); + expect(analytics, isNot(isA())); + }); + + testWithoutContext('NoOp instance for user branch', () { + final Analytics analytics = getAnalytics( + runningOnBot: false, + flutterVersion: FakeFlutterVersion( + branch: userBranch, + frameworkRevision: '3.14.0-14.0.pre.370', + ), + environment: const {}, + analyticsOverride: analyticsOverride, + ); + + expect( + analytics.clientId, + NoOpAnalytics.staticClientId, + reason: 'The client ID should match the NoOp client id', + ); + expect(analytics, isA()); + }); + + testWithoutContext('NoOp instance for unknown branch', () { + final Analytics analytics = getAnalytics( + runningOnBot: false, + flutterVersion: FakeFlutterVersion( + frameworkRevision: 'unknown', + ), + environment: const {}, + analyticsOverride: analyticsOverride, + ); + + expect( + analytics.clientId, + NoOpAnalytics.staticClientId, + reason: 'The client ID should match the NoOp client id', + ); + expect(analytics, isA()); + }); + + testWithoutContext('NoOp instance when running on bots', () { + final Analytics analytics = getAnalytics( + runningOnBot: true, + flutterVersion: FakeFlutterVersion(), + environment: const {}, + analyticsOverride: analyticsOverride, + ); + + expect( + analytics.clientId, + NoOpAnalytics.staticClientId, + reason: 'The client ID should match the NoOp client id', + ); + expect(analytics, isA()); + }); + + testWithoutContext('NoOp instance when suppressing via env variable', () { + final Analytics analytics = getAnalytics( + runningOnBot: true, + flutterVersion: FakeFlutterVersion(), + environment: const {'FLUTTER_SUPPRESS_ANALYTICS': 'true'}, + analyticsOverride: analyticsOverride, + ); + + expect( + analytics.clientId, + NoOpAnalytics.staticClientId, + reason: 'The client ID should match the NoOp client id', + ); + expect(analytics, isA()); + }); + }); +} diff --git a/packages/flutter_tools/test/general.shard/update_packages_test.dart b/packages/flutter_tools/test/general.shard/update_packages_test.dart index 7b2ecd82b064e..1bfe39ada9538 100644 --- a/packages/flutter_tools/test/general.shard/update_packages_test.dart +++ b/packages/flutter_tools/test/general.shard/update_packages_test.dart @@ -107,6 +107,8 @@ void main() { 'video_player', 'material_color_utilities', 'archive', + 'leak_tracker', + 'leak_tracker_flutter_testing', ]), ); }); diff --git a/packages/flutter_tools/test/general.shard/vmservice_test.dart b/packages/flutter_tools/test/general.shard/vmservice_test.dart index 73e710c6567af..2557b3a289758 100644 --- a/packages/flutter_tools/test/general.shard/vmservice_test.dart +++ b/packages/flutter_tools/test/general.shard/vmservice_test.dart @@ -442,10 +442,6 @@ void main() { method: kListViewsMethod, errorCode: RPCErrorCodes.kServiceDisappeared, ), - const FakeVmServiceRequest( - method: kScreenshotMethod, - errorCode: RPCErrorCodes.kServiceDisappeared, - ), const FakeVmServiceRequest( method: kScreenshotSkpMethod, errorCode: RPCErrorCodes.kServiceDisappeared, @@ -480,9 +476,6 @@ void main() { final List views = await fakeVmServiceHost.vmService.getFlutterViews(); expect(views, isEmpty); - final vm_service.Response? screenshot = await fakeVmServiceHost.vmService.screenshot(); - expect(screenshot, isNull); - final vm_service.Response? screenshotSkp = await fakeVmServiceHost.vmService.screenshotSkp(); expect(screenshotSkp, isNull); diff --git a/packages/flutter_tools/test/general.shard/windows/native_assets_test.dart b/packages/flutter_tools/test/general.shard/windows/native_assets_test.dart new file mode 100644 index 0000000000000..71a52fed23559 --- /dev/null +++ b/packages/flutter_tools/test/general.shard/windows/native_assets_test.dart @@ -0,0 +1,439 @@ +// Copyright 2014 The Flutter 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:file/file.dart'; +import 'package:file/memory.dart'; +import 'package:file_testing/file_testing.dart'; +import 'package:flutter_tools/src/artifacts.dart'; +import 'package:flutter_tools/src/base/file_system.dart'; +import 'package:flutter_tools/src/base/logger.dart'; +import 'package:flutter_tools/src/base/platform.dart'; +import 'package:flutter_tools/src/build_info.dart'; +import 'package:flutter_tools/src/build_system/build_system.dart'; +import 'package:flutter_tools/src/dart/package_map.dart'; +import 'package:flutter_tools/src/features.dart'; +import 'package:flutter_tools/src/globals.dart' as globals; +import 'package:flutter_tools/src/native_assets.dart'; +import 'package:flutter_tools/src/windows/native_assets.dart'; +import 'package:native_assets_cli/native_assets_cli.dart' hide BuildMode, Target; +import 'package:native_assets_cli/native_assets_cli.dart' as native_assets_cli; +import 'package:package_config/package_config_types.dart'; + +import '../../src/common.dart'; +import '../../src/context.dart'; +import '../../src/fakes.dart'; +import '../fake_native_assets_build_runner.dart'; + +void main() { + late FakeProcessManager processManager; + late Environment environment; + late Artifacts artifacts; + late FileSystem fileSystem; + late BufferLogger logger; + late Uri projectUri; + + setUp(() { + processManager = FakeProcessManager.empty(); + logger = BufferLogger.test(); + artifacts = Artifacts.test(); + fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows); + environment = Environment.test( + fileSystem.currentDirectory, + inputs: {}, + artifacts: artifacts, + processManager: processManager, + fileSystem: fileSystem, + logger: logger, + ); + environment.buildDir.createSync(recursive: true); + projectUri = environment.projectDir.uri; + }); + + testUsingContext('dry run with no package config', overrides: { + ProcessManager: () => FakeProcessManager.empty(), + }, () async { + expect( + await dryRunNativeAssetsWindows( + projectUri: projectUri, + fileSystem: fileSystem, + buildRunner: FakeNativeAssetsBuildRunner( + hasPackageConfigResult: false, + ), + ), + null, + ); + expect( + (globals.logger as BufferLogger).traceText, + contains('No package config found. Skipping native assets compilation.'), + ); + }); + + testUsingContext('build with no package config', overrides: { + ProcessManager: () => FakeProcessManager.empty(), + }, () async { + await buildNativeAssetsWindows( + projectUri: projectUri, + buildMode: BuildMode.debug, + fileSystem: fileSystem, + buildRunner: FakeNativeAssetsBuildRunner( + hasPackageConfigResult: false, + ), + ); + expect( + (globals.logger as BufferLogger).traceText, + contains('No package config found. Skipping native assets compilation.'), + ); + }); + + testUsingContext('dry run for multiple OSes with no package config', overrides: { + ProcessManager: () => FakeProcessManager.empty(), + }, () async { + await dryRunNativeAssetsMultipeOSes( + projectUri: projectUri, + fileSystem: fileSystem, + targetPlatforms: [ + TargetPlatform.windows_x64, + ], + buildRunner: FakeNativeAssetsBuildRunner( + hasPackageConfigResult: false, + ), + ); + expect( + (globals.logger as BufferLogger).traceText, + contains('No package config found. Skipping native assets compilation.'), + ); + }); + + testUsingContext('dry run with assets but not enabled', overrides: { + ProcessManager: () => FakeProcessManager.empty(), + }, () async { + final File packageConfig = environment.projectDir.childFile('.dart_tool/package_config.json'); + await packageConfig.parent.create(); + await packageConfig.create(); + expect( + () => dryRunNativeAssetsWindows( + projectUri: projectUri, + fileSystem: fileSystem, + buildRunner: FakeNativeAssetsBuildRunner( + packagesWithNativeAssetsResult: [ + Package('bar', projectUri), + ], + ), + ), + throwsToolExit( + message: 'Package(s) bar require the native assets feature to be enabled. ' + 'Enable using `flutter config --enable-native-assets`.', + ), + ); + }); + + testUsingContext('dry run with assets', overrides: { + FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true), + ProcessManager: () => FakeProcessManager.empty(), + }, () async { + final File packageConfig = environment.projectDir.childFile('.dart_tool/package_config.json'); + await packageConfig.parent.create(); + await packageConfig.create(); + final Uri? nativeAssetsYaml = await dryRunNativeAssetsWindows( + projectUri: projectUri, + fileSystem: fileSystem, + buildRunner: FakeNativeAssetsBuildRunner( + packagesWithNativeAssetsResult: [ + Package('bar', projectUri), + ], + dryRunResult: FakeNativeAssetsBuilderResult( + assets: [ + Asset( + id: 'package:bar/bar.dart', + linkMode: LinkMode.dynamic, + target: native_assets_cli.Target.windowsX64, + path: AssetAbsolutePath(Uri.file('bar.dll')), + ), + ], + ), + ), + ); + expect( + (globals.logger as BufferLogger).traceText, + stringContainsInOrder([ + 'Dry running native assets for windows.', + 'Dry running native assets for windows done.', + ]), + ); + expect( + nativeAssetsYaml, + projectUri.resolve('build/native_assets/windows/native_assets.yaml'), + ); + expect( + await fileSystem.file(nativeAssetsYaml).readAsString(), + contains('package:bar/bar.dart'), + ); + }); + + testUsingContext('build with assets but not enabled', overrides: { + ProcessManager: () => FakeProcessManager.empty(), + }, () async { + final File packageConfig = environment.projectDir.childFile('.dart_tool/package_config.json'); + await packageConfig.parent.create(); + await packageConfig.create(); + expect( + () => buildNativeAssetsWindows( + projectUri: projectUri, + buildMode: BuildMode.debug, + fileSystem: fileSystem, + buildRunner: FakeNativeAssetsBuildRunner( + packagesWithNativeAssetsResult: [ + Package('bar', projectUri), + ], + ), + ), + throwsToolExit( + message: 'Package(s) bar require the native assets feature to be enabled. ' + 'Enable using `flutter config --enable-native-assets`.', + ), + ); + }); + + testUsingContext('build no assets', overrides: { + FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true), + ProcessManager: () => FakeProcessManager.empty(), + }, () async { + final File packageConfig = environment.projectDir.childFile('.dart_tool/package_config.json'); + await packageConfig.parent.create(); + await packageConfig.create(); + final (Uri? nativeAssetsYaml, _) = await buildNativeAssetsWindows( + targetPlatform: TargetPlatform.windows_x64, + projectUri: projectUri, + buildMode: BuildMode.debug, + fileSystem: fileSystem, + buildRunner: FakeNativeAssetsBuildRunner( + packagesWithNativeAssetsResult: [ + Package('bar', projectUri), + ], + ), + ); + expect( + nativeAssetsYaml, + projectUri.resolve('build/native_assets/windows/native_assets.yaml'), + ); + expect( + await fileSystem.file(nativeAssetsYaml).readAsString(), + isNot(contains('package:bar/bar.dart')), + ); + expect( + environment.projectDir.childDirectory('build').childDirectory('native_assets').childDirectory('windows'), + exists, + ); + }); + + for (final bool flutterTester in [false, true]) { + String testName = ''; + if (flutterTester) { + testName += ' flutter tester'; + } + testUsingContext('build with assets$testName', overrides: { + FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true), + ProcessManager: () => FakeProcessManager.empty(), + }, () async { + final File packageConfig = environment.projectDir.childDirectory('.dart_tool').childFile('package_config.json'); + await packageConfig.parent.create(); + await packageConfig.create(); + final File dylibAfterCompiling = fileSystem.file('bar.dll'); + // The mock doesn't create the file, so create it here. + await dylibAfterCompiling.create(); + final (Uri? nativeAssetsYaml, _) = await buildNativeAssetsWindows( + targetPlatform: TargetPlatform.windows_x64, + projectUri: projectUri, + buildMode: BuildMode.debug, + fileSystem: fileSystem, + flutterTester: flutterTester, + buildRunner: FakeNativeAssetsBuildRunner( + packagesWithNativeAssetsResult: [ + Package('bar', projectUri), + ], + buildResult: FakeNativeAssetsBuilderResult( + assets: [ + Asset( + id: 'package:bar/bar.dart', + linkMode: LinkMode.dynamic, + target: native_assets_cli.Target.windowsX64, + path: AssetAbsolutePath(dylibAfterCompiling.uri), + ), + ], + ), + ), + ); + expect( + (globals.logger as BufferLogger).traceText, + stringContainsInOrder([ + 'Building native assets for windows_x64 debug.', + 'Building native assets for windows_x64 done.', + ]), + ); + expect( + nativeAssetsYaml, + projectUri.resolve('build/native_assets/windows/native_assets.yaml'), + ); + expect( + await fileSystem.file(nativeAssetsYaml).readAsString(), + stringContainsInOrder([ + 'package:bar/bar.dart', + if (flutterTester) + // Tests run on host system, so the have the full path on the system. + '- ${projectUri.resolve('build/native_assets/windows/bar.dll').toFilePath()}' + else + // Apps are a bundle with the dylibs on their dlopen path. + '- bar.dll', + ]), + ); + }); + } + + testUsingContext('static libs not supported', overrides: { + FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true), + ProcessManager: () => FakeProcessManager.empty(), + }, () async { + final File packageConfig = environment.projectDir.childFile('.dart_tool/package_config.json'); + await packageConfig.parent.create(); + await packageConfig.create(); + expect( + () => dryRunNativeAssetsWindows( + projectUri: projectUri, + fileSystem: fileSystem, + buildRunner: FakeNativeAssetsBuildRunner( + packagesWithNativeAssetsResult: [ + Package('bar', projectUri), + ], + dryRunResult: FakeNativeAssetsBuilderResult( + assets: [ + Asset( + id: 'package:bar/bar.dart', + linkMode: LinkMode.static, + target: native_assets_cli.Target.windowsX64, + path: AssetAbsolutePath(Uri.file(OS.windows.staticlibFileName('bar'))), + ), + ], + ), + ), + ), + throwsToolExit( + message: 'Native asset(s) package:bar/bar.dart have their link mode set to ' + 'static, but this is not yet supported. ' + 'For more info see https://github.com/dart-lang/sdk/issues/49418.', + ), + ); + }); + + // This logic is mocked in the other tests to avoid having test order + // randomization causing issues with what processes are invoked. + // Exercise the parsing of the process output in this separate test. + testUsingContext('NativeAssetsBuildRunnerImpl.cCompilerConfig', overrides: { + FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true), + ProcessManager: () => FakeProcessManager.list( + [ + FakeCommand( + command: [ + RegExp(r'(.*)vswhere.exe'), + '-format', + 'json', + '-products', + '*', + '-utf8', + '-latest', + '-version', + '16', + '-requires', + 'Microsoft.VisualStudio.Workload.NativeDesktop', + 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64', + 'Microsoft.VisualStudio.Component.VC.CMake.Project', + ], + stdout: r''' +[ + { + "instanceId": "491ec752", + "installDate": "2023-04-21T08:17:11Z", + "installationName": "VisualStudio/17.5.4+33530.505", + "installationPath": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community", + "installationVersion": "17.5.33530.505", + "productId": "Microsoft.VisualStudio.Product.Community", + "productPath": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\Common7\\IDE\\devenv.exe", + "state": 4294967295, + "isComplete": true, + "isLaunchable": true, + "isPrerelease": false, + "isRebootRequired": false, + "displayName": "Visual Studio Community 2022", + "description": "Powerful IDE, free for students, open-source contributors, and individuals", + "channelId": "VisualStudio.17.Release", + "channelUri": "https://aka.ms/vs/17/release/channel", + "enginePath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\resources\\app\\ServiceHub\\Services\\Microsoft.VisualStudio.Setup.Service", + "installedChannelId": "VisualStudio.17.Release", + "installedChannelUri": "https://aka.ms/vs/17/release/channel", + "releaseNotes": "https://docs.microsoft.com/en-us/visualstudio/releases/2022/release-notes-v17.5#17.5.4", + "thirdPartyNotices": "https://go.microsoft.com/fwlink/?LinkId=661288", + "updateDate": "2023-04-21T08:17:11.2249473Z", + "catalog": { + "buildBranch": "d17.5", + "buildVersion": "17.5.33530.505", + "id": "VisualStudio/17.5.4+33530.505", + "localBuild": "build-lab", + "manifestName": "VisualStudio", + "manifestType": "installer", + "productDisplayVersion": "17.5.4", + "productLine": "Dev17", + "productLineVersion": "2022", + "productMilestone": "RTW", + "productMilestoneIsPreRelease": "False", + "productName": "Visual Studio", + "productPatchVersion": "4", + "productPreReleaseMilestoneSuffix": "1.0", + "productSemanticVersion": "17.5.4+33530.505", + "requiredEngineVersion": "3.5.2150.18781" + }, + "properties": { + "campaignId": "2060:abb99c5d1ecc4013acf2e1814b10b690", + "channelManifestId": "VisualStudio.17.Release/17.5.4+33530.505", + "nickname": "", + "setupEngineFilePath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\setup.exe" + } + } +] +''', // Newline at the end of the string. + ) + ], + ), + FileSystem: () => fileSystem, + }, () async { + if (!const LocalPlatform().isWindows) { + return; + } + + final Directory msvcBinDir = + fileSystem.directory(r'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\bin\Hostx64\x64'); + await msvcBinDir.create(recursive: true); + + final File packagesFile = fileSystem + .directory(projectUri) + .childDirectory('.dart_tool') + .childFile('package_config.json'); + await packagesFile.parent.create(); + await packagesFile.create(); + final PackageConfig packageConfig = await loadPackageConfigWithLogging( + packagesFile, + logger: environment.logger, + ); + final NativeAssetsBuildRunner runner = NativeAssetsBuildRunnerImpl( + projectUri, + packageConfig, + fileSystem, + logger, + ); + final CCompilerConfig result = await runner.cCompilerConfig; + expect(result.cc?.toFilePath(), msvcBinDir.childFile('cl.exe').uri.toFilePath()); + expect(result.ar?.toFilePath(), msvcBinDir.childFile('lib.exe').uri.toFilePath()); + expect(result.ld?.toFilePath(), msvcBinDir.childFile('link.exe').uri.toFilePath()); + expect(result.envScript, isNotNull); + expect(result.envScriptArgs, isNotNull); + }); +} diff --git a/packages/flutter_tools/test/general.shard/windows/visual_studio_test.dart b/packages/flutter_tools/test/general.shard/windows/visual_studio_test.dart index 6f2aa45411a32..57b07e929e280 100644 --- a/packages/flutter_tools/test/general.shard/windows/visual_studio_test.dart +++ b/packages/flutter_tools/test/general.shard/windows/visual_studio_test.dart @@ -11,12 +11,16 @@ import 'package:flutter_tools/src/convert.dart'; import 'package:flutter_tools/src/windows/visual_studio.dart'; import '../../src/common.dart'; -import '../../src/fake_process_manager.dart'; +import '../../src/context.dart'; const String programFilesPath = r'C:\Program Files (x86)'; const String visualStudioPath = programFilesPath + r'\Microsoft Visual Studio\2017\Community'; const String cmakePath = visualStudioPath + r'\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe'; const String vswherePath = programFilesPath + r'\Microsoft Visual Studio\Installer\vswhere.exe'; +const String clPath = visualStudioPath + r'\VC\Tools\MSVC\14.35.32215\bin\Hostx64\x64\cl.exe'; +const String libPath = visualStudioPath + r'\VC\Tools\MSVC\14.35.32215\bin\Hostx64\x64\lib.exe'; +const String linkPath = visualStudioPath + r'\VC\Tools\MSVC\14.35.32215\bin\Hostx64\x64\link.exe'; +const String vcvarsPath = visualStudioPath + r'\VC\Auxiliary\Build\vcvars64.bat'; final Platform windowsPlatform = FakePlatform( operatingSystem: 'windows', @@ -140,6 +144,7 @@ void setMockVswhereResponse( ]) { fileSystem.file(vswherePath).createSync(recursive: true); fileSystem.file(cmakePath).createSync(recursive: true); + fileSystem.file(clPath).createSync(recursive: true); final String finalResponse = responseOverride ?? (response != null ? json.encode(>[response]) : '[]'); final List requirementArguments = requiredComponents == null @@ -300,11 +305,11 @@ void setMockSdkRegResponse( const String registryKey = r'InstallationFolder'; const String installationPath = r'C:\Program Files (x86)\Windows Kits\10\'; final String stdout = registryPresent - ? ''' + ? ''' $registryPath $registryKey REG_SZ $installationPath ''' - : ''' + : ''' ERROR: The system was unable to find the specified registry key or value. '''; @@ -776,6 +781,10 @@ void main() { expect(visualStudio.hasNecessaryComponents, true); expect(visualStudio.cmakePath, equals(cmakePath)); expect(visualStudio.cmakeGenerator, equals('Visual Studio 16 2019')); + expect(visualStudio.clPath, equals(clPath)); + expect(visualStudio.libPath, equals(libPath)); + expect(visualStudio.linkPath, equals(linkPath)); + expect(visualStudio.vcvarsPath, equals(vcvarsPath)); }); testWithoutContext('Everything returns good values when Build Tools is present with all components', () { @@ -814,6 +823,10 @@ void main() { expect(visualStudio.hasNecessaryComponents, true); expect(visualStudio.cmakePath, equals(cmakePath)); expect(visualStudio.cmakeGenerator, equals('Visual Studio 17 2022')); + expect(visualStudio.clPath, equals(clPath)); + expect(visualStudio.libPath, equals(libPath)); + expect(visualStudio.linkPath, equals(linkPath)); + expect(visualStudio.vcvarsPath, equals(vcvarsPath)); }); testWithoutContext('Metadata is for compatible version when latest is missing components', () { @@ -905,8 +918,7 @@ void main() { }); testWithoutContext('Ignores unicode replacement char in unused properties', () { - final Map response = Map.of(_defaultResponse) - ..['unused'] = 'Bad UTF8 \u{FFFD}'; + final Map response = Map.of(_defaultResponse)..['unused'] = 'Bad UTF8 \u{FFFD}'; setMockCompatibleVisualStudioInstallation( response, @@ -919,6 +931,10 @@ void main() { expect(visualStudio.hasNecessaryComponents, true); expect(visualStudio.cmakePath, equals(cmakePath)); expect(visualStudio.cmakeGenerator, equals('Visual Studio 16 2019')); + expect(visualStudio.clPath, equals(clPath)); + expect(visualStudio.libPath, equals(libPath)); + expect(visualStudio.linkPath, equals(linkPath)); + expect(visualStudio.vcvarsPath, equals(vcvarsPath)); }); testWithoutContext('Throws ToolExit on bad UTF-8 in installationPath', () { @@ -953,13 +969,16 @@ void main() { expect(visualStudio.cmakePath, equals(cmakePath)); expect(visualStudio.cmakeGenerator, equals('Visual Studio 16 2019')); expect(visualStudio.displayName, equals('\u{FFFD}')); + expect(visualStudio.clPath, equals(clPath)); + expect(visualStudio.libPath, equals(libPath)); + expect(visualStudio.linkPath, equals(linkPath)); + expect(visualStudio.vcvarsPath, equals(vcvarsPath)); }); testWithoutContext("Ignores bad UTF-8 in catalog's productDisplayVersion", () { final Map catalog = Map.of(_defaultResponse['catalog'] as Map) ..['productDisplayVersion'] = '\u{FFFD}'; - final Map response = Map.of(_defaultResponse) - ..['catalog'] = catalog; + final Map response = Map.of(_defaultResponse)..['catalog'] = catalog; setMockCompatibleVisualStudioInstallation(response, fixture.fileSystem, fixture.processManager); @@ -969,6 +988,10 @@ void main() { expect(visualStudio.cmakePath, equals(cmakePath)); expect(visualStudio.cmakeGenerator, equals('Visual Studio 16 2019')); expect(visualStudio.displayVersion, equals('\u{FFFD}')); + expect(visualStudio.clPath, equals(clPath)); + expect(visualStudio.libPath, equals(libPath)); + expect(visualStudio.linkPath, equals(linkPath)); + expect(visualStudio.vcvarsPath, equals(vcvarsPath)); }); testWithoutContext('Ignores malformed JSON in description property', () { @@ -987,101 +1010,109 @@ void main() { expect(visualStudio.cmakePath, equals(cmakePath)); expect(visualStudio.cmakeGenerator, equals('Visual Studio 16 2019')); expect(visualStudio.displayVersion, equals('16.2.5')); + expect(visualStudio.clPath, equals(clPath)); + expect(visualStudio.libPath, equals(libPath)); + expect(visualStudio.linkPath, equals(linkPath)); + expect(visualStudio.vcvarsPath, equals(vcvarsPath)); expect(fixture.logger.warningText, isEmpty); }); }); group(VswhereDetails, () { - test('Accepts empty JSON', () { - const bool meetsRequirements = true; - final Map json = {}; - - final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json); - - expect(result.installationPath, null); - expect(result.displayName, null); - expect(result.fullVersion, null); - expect(result.isComplete, null); - expect(result.isLaunchable, null); - expect(result.isRebootRequired, null); - expect(result.isPrerelease, null); - expect(result.catalogDisplayVersion, null); - expect(result.isUsable, isTrue); - }); - - test('Ignores unknown JSON properties', () { - const bool meetsRequirements = true; - final Map json = { - 'hello': 'world', - }; - - final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json); - - expect(result.installationPath, null); - expect(result.displayName, null); - expect(result.fullVersion, null); - expect(result.isComplete, null); - expect(result.isLaunchable, null); - expect(result.isRebootRequired, null); - expect(result.isPrerelease, null); - expect(result.catalogDisplayVersion, null); - expect(result.isUsable, isTrue); - }); - - test('Accepts JSON', () { - const bool meetsRequirements = true; - - final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, _defaultResponse); - - expect(result.installationPath, visualStudioPath); - expect(result.displayName, 'Visual Studio Community 2019'); - expect(result.fullVersion, '16.2.29306.81'); - expect(result.isComplete, true); - expect(result.isLaunchable, true); - expect(result.isRebootRequired, false); - expect(result.isPrerelease, false); - expect(result.catalogDisplayVersion, '16.2.5'); - expect(result.isUsable, isTrue); - }); - - test('Installation that does not satisfy requirements is not usable', () { - const bool meetsRequirements = false; - - final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, _defaultResponse); - - expect(result.isUsable, isFalse); - }); - - test('Incomplete installation is not usable', () { - const bool meetsRequirements = true; - final Map json = Map.of(_defaultResponse) - ..['isComplete'] = false; - - final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json); - - expect(result.isUsable, isFalse); - }); - - test('Unlaunchable installation is not usable', () { - const bool meetsRequirements = true; - final Map json = Map.of(_defaultResponse) - ..['isLaunchable'] = false; - - final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json); - - expect(result.isUsable, isFalse); - }); - - test('Installation that requires reboot is not usable', () { - const bool meetsRequirements = true; - final Map json = Map.of(_defaultResponse) - ..['isRebootRequired'] = true; - - final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json); - - expect(result.isUsable, isFalse); - }); + test('Accepts empty JSON', () { + const bool meetsRequirements = true; + final Map json = {}; + const String msvcVersion = ''; + + final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json, msvcVersion); + + expect(result.installationPath, null); + expect(result.displayName, null); + expect(result.fullVersion, null); + expect(result.isComplete, null); + expect(result.isLaunchable, null); + expect(result.isRebootRequired, null); + expect(result.isPrerelease, null); + expect(result.catalogDisplayVersion, null); + expect(result.isUsable, isTrue); + }); + + test('Ignores unknown JSON properties', () { + const bool meetsRequirements = true; + final Map json = { + 'hello': 'world', + }; + const String msvcVersion = ''; + + final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json, msvcVersion); + + expect(result.installationPath, null); + expect(result.displayName, null); + expect(result.fullVersion, null); + expect(result.isComplete, null); + expect(result.isLaunchable, null); + expect(result.isRebootRequired, null); + expect(result.isPrerelease, null); + expect(result.catalogDisplayVersion, null); + expect(result.isUsable, isTrue); + }); + + test('Accepts JSON', () { + const bool meetsRequirements = true; + const String msvcVersion = ''; + + final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, _defaultResponse, msvcVersion); + + expect(result.installationPath, visualStudioPath); + expect(result.displayName, 'Visual Studio Community 2019'); + expect(result.fullVersion, '16.2.29306.81'); + expect(result.isComplete, true); + expect(result.isLaunchable, true); + expect(result.isRebootRequired, false); + expect(result.isPrerelease, false); + expect(result.catalogDisplayVersion, '16.2.5'); + expect(result.isUsable, isTrue); + }); + + test('Installation that does not satisfy requirements is not usable', () { + const bool meetsRequirements = false; + const String msvcVersion = ''; + + final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, _defaultResponse, msvcVersion); + + expect(result.isUsable, isFalse); + }); + + test('Incomplete installation is not usable', () { + const bool meetsRequirements = true; + final Map json = Map.of(_defaultResponse)..['isComplete'] = false; + const String msvcVersion = ''; + + final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json, msvcVersion); + + expect(result.isUsable, isFalse); + }); + + test('Unlaunchable installation is not usable', () { + const bool meetsRequirements = true; + final Map json = Map.of(_defaultResponse)..['isLaunchable'] = false; + const String msvcVersion = ''; + + final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json, msvcVersion); + + expect(result.isUsable, isFalse); + }); + + test('Installation that requires reboot is not usable', () { + const bool meetsRequirements = true; + final Map json = Map.of(_defaultResponse)..['isRebootRequired'] = true; + const String msvcVersion = ''; + + final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json, msvcVersion); + + expect(result.isUsable, isFalse); + }); }); } diff --git a/packages/flutter_tools/test/integration.shard/command_output_test.dart b/packages/flutter_tools/test/integration.shard/command_output_test.dart index 7b72ef67643b6..60c34113dec4f 100644 --- a/packages/flutter_tools/test/integration.shard/command_output_test.dart +++ b/packages/flutter_tools/test/integration.shard/command_output_test.dart @@ -71,11 +71,12 @@ void main() { expect(result.stdout, contains('Shutdown hooks complete')); }); - testWithoutContext('flutter config contains all features', () async { + testWithoutContext('flutter config --list contains all features', () async { final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'); final ProcessResult result = await processManager.run([ flutterBin, 'config', + '--list' ]); // contains all of the experiments in features.dart diff --git a/packages/flutter_tools/test/integration.shard/native_assets_test.dart b/packages/flutter_tools/test/integration.shard/native_assets_test.dart index c6824fb35774e..3456c6a224b6f 100644 --- a/packages/flutter_tools/test/integration.shard/native_assets_test.dart +++ b/packages/flutter_tools/test/integration.shard/native_assets_test.dart @@ -58,8 +58,8 @@ const String packageName = 'package_with_native_assets'; const String exampleAppName = '${packageName}_example'; void main() { - if (!platform.isMacOS && !platform.isLinux) { - // TODO(dacoharkes): Implement other OSes. https://github.com/flutter/flutter/issues/129757 + if (!platform.isMacOS && !platform.isLinux && !platform.isWindows) { + // TODO(dacoharkes): Implement Fuchsia. https://github.com/flutter/flutter/issues/129757 return; } @@ -146,9 +146,10 @@ void main() { if (device == 'macos') { expectDylibIsBundledMacOS(exampleDirectory, buildMode); - } - if (device == 'linux') { + } else if (device == 'linux') { expectDylibIsBundledLinux(exampleDirectory, buildMode); + } else if (device == 'windows') { + expectDylibIsBundledWindows(exampleDirectory, buildMode); } if (device == hostOs) { expectCCompilerIsConfigured(exampleDirectory); @@ -205,6 +206,8 @@ void main() { expectDylibIsBundledIos(exampleDirectory, buildMode); } else if (buildSubcommand == 'linux') { expectDylibIsBundledLinux(exampleDirectory, buildMode); + } else if (buildSubcommand == 'windows') { + expectDylibIsBundledWindows(exampleDirectory, buildMode); } expectCCompilerIsConfigured(exampleDirectory); }); @@ -239,11 +242,15 @@ void main() { 'build', buildSubcommand, if (buildSubcommand == 'ios') '--no-codesign', + if (buildSubcommand == 'windows') '-v' // Requires verbose mode for error. ], workingDirectory: exampleDirectory.path, ); expect(result.exitCode, isNot(0)); - expect(result.stderr, contains('link mode set to static, but this is not yet supported')); + expect( + (result.stdout as String) + (result.stderr as String), + contains('link mode set to static, but this is not yet supported'), + ); }); }); } @@ -301,14 +308,36 @@ void expectDylibIsBundledIos(Directory appDirectory, String buildMode) { void expectDylibIsBundledLinux(Directory appDirectory, String buildMode) { // Linux does not support cross compilation, so always only check current architecture. final String architecture = Architecture.current.dartPlatform; - final Directory appBundle = appDirectory.childDirectory('build/$hostOs/$architecture/$buildMode/bundle/'); + final Directory appBundle = appDirectory + .childDirectory('build') + .childDirectory(hostOs) + .childDirectory(architecture) + .childDirectory(buildMode) + .childDirectory('bundle'); expect(appBundle, exists); - final Directory dylibsFolder = appBundle.childDirectory('lib/'); + final Directory dylibsFolder = appBundle.childDirectory('lib'); expect(dylibsFolder, exists); final File dylib = dylibsFolder.childFile(OS.linux.dylibFileName(packageName)); expect(dylib, exists); } +/// Checks that dylibs are bundled. +/// +/// Sample path: build\windows\x64\runner\Debug\my_package_example.exe +void expectDylibIsBundledWindows(Directory appDirectory, String buildMode) { + // Linux does not support cross compilation, so always only check current architecture. + final String architecture = Architecture.current.dartPlatform; + final Directory appBundle = appDirectory + .childDirectory('build') + .childDirectory(hostOs) + .childDirectory(architecture) + .childDirectory('runner') + .childDirectory(buildMode.upperCaseFirst()); + expect(appBundle, exists); + final File dylib = appBundle.childFile(OS.windows.dylibFileName(packageName)); + expect(dylib, exists); +} + /// For `flutter build` we can't easily test whether running the app works. /// Check that we have the dylibs in the app. void expectDylibIsBundledWithFrameworks(Directory appDirectory, String buildMode, String os) { diff --git a/packages/flutter_tools/test/src/context.dart b/packages/flutter_tools/test/src/context.dart index 7bea7532c3f5b..f0f4fd0f7d162 100644 --- a/packages/flutter_tools/test/src/context.dart +++ b/packages/flutter_tools/test/src/context.dart @@ -35,6 +35,7 @@ import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/version.dart'; import 'package:meta/meta.dart'; import 'package:test/fake.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import 'common.dart'; import 'fake_http_client.dart'; @@ -120,6 +121,7 @@ void testUsingContext( Pub: () => ThrowingPub(), // prevent accidentally using pub. CrashReporter: () => const NoopCrashReporter(), TemplateRenderer: () => const MustacheTemplateRenderer(), + Analytics: () => NoOpAnalytics(), }, body: () { return runZonedGuarded>(() { diff --git a/packages/flutter_tools/test/src/fake_process_manager.dart b/packages/flutter_tools/test/src/fake_process_manager.dart index 427f19a5233ac..305a37cbf968f 100644 --- a/packages/flutter_tools/test/src/fake_process_manager.dart +++ b/packages/flutter_tools/test/src/fake_process_manager.dart @@ -213,10 +213,17 @@ class FakeProcess implements io.Process { /// The raw byte content of stdout. final List _stdout; + /// The list of [kill] signals this process received so far. + @visibleForTesting + List get signals => _signals; + final List _signals = []; + @override bool kill([io.ProcessSignal signal = io.ProcessSignal.sigterm]) { + _signals.add(signal); + // Killing a fake process has no effect. - return false; + return true; } } @@ -400,6 +407,7 @@ abstract class FakeProcessManager implements ProcessManager { if (fakeProcess == null) { return false; } + fakeProcess.kill(signal); if (fakeProcess._completer != null) { fakeProcess._completer.complete(); } diff --git a/packages/flutter_tools/test/src/fakes.dart b/packages/flutter_tools/test/src/fakes.dart index 4cc4ab1c227e8..e8dec45f6f217 100644 --- a/packages/flutter_tools/test/src/fakes.dart +++ b/packages/flutter_tools/test/src/fakes.dart @@ -426,7 +426,7 @@ class FakeFlutterVersion implements FlutterVersion { @override String getVersionString({bool redactUnknownBranches = false}) { - return 'v0.0.0'; + return '${getBranchName(redactUnknownBranches: redactUnknownBranches)}/$frameworkRevision'; } @override diff --git a/packages/flutter_tools/test/web.shard/chrome_test.dart b/packages/flutter_tools/test/web.shard/chrome_test.dart index 0c6c1ea4f0b2a..f9611f4e7ee0c 100644 --- a/packages/flutter_tools/test/web.shard/chrome_test.dart +++ b/packages/flutter_tools/test/web.shard/chrome_test.dart @@ -3,7 +3,9 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:io' as io; +import 'package:fake_async/fake_async.dart'; import 'package:file/memory.dart'; import 'package:file_testing/file_testing.dart'; import 'package:flutter_tools/src/base/file_system.dart'; @@ -16,7 +18,7 @@ import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; import '../src/common.dart'; import '../src/fake_process_manager.dart'; -import '../src/fakes.dart'; +import '../src/fakes.dart' hide FakeProcess; const List kChromeArgs = [ '--disable-background-timer-throttling', @@ -165,6 +167,116 @@ void main() { ); }); + testWithoutContext('exits normally using SIGTERM', () async { + final BufferLogger logger = BufferLogger.test(); + final FakeAsync fakeAsync = FakeAsync(); + + fakeAsync.run((_) { + () async { + final FakeChromeConnection chromeConnection = FakeChromeConnection(maxRetries: 4); + final ChromiumLauncher chromiumLauncher = ChromiumLauncher( + fileSystem: fileSystem, + platform: platform, + processManager: processManager, + operatingSystemUtils: operatingSystemUtils, + browserFinder: findChromeExecutable, + logger: logger, + ); + + final FakeProcess process = FakeProcess( + duration: const Duration(seconds: 3), + ); + + final Chromium chrome = Chromium(0, chromeConnection, chromiumLauncher: chromiumLauncher, process: process, logger: logger); + + final Future closeFuture = chrome.close(); + fakeAsync.elapse(const Duration(seconds: 4)); + await closeFuture; + + expect(process.signals, [io.ProcessSignal.sigterm]); + }(); + }); + + fakeAsync.flushTimers(); + expect(logger.warningText, isEmpty); + }); + + testWithoutContext('falls back to SIGKILL if SIGTERM did not work', () async { + final BufferLogger logger = BufferLogger.test(); + final FakeAsync fakeAsync = FakeAsync(); + + fakeAsync.run((_) { + () async { + final FakeChromeConnection chromeConnection = FakeChromeConnection(maxRetries: 4); + final ChromiumLauncher chromiumLauncher = ChromiumLauncher( + fileSystem: fileSystem, + platform: platform, + processManager: processManager, + operatingSystemUtils: operatingSystemUtils, + browserFinder: findChromeExecutable, + logger: logger, + ); + + final FakeProcess process = FakeProcess( + duration: const Duration(seconds: 6), + ); + + final Chromium chrome = Chromium(0, chromeConnection, chromiumLauncher: chromiumLauncher, process: process, logger: logger); + + final Future closeFuture = chrome.close(); + fakeAsync.elapse(const Duration(seconds: 7)); + await closeFuture; + + expect(process.signals, [io.ProcessSignal.sigterm, io.ProcessSignal.sigkill]); + }(); + }); + + fakeAsync.flushTimers(); + expect( + logger.warningText, + 'Failed to exit Chromium (pid: 1234) using SIGTERM. Will try sending SIGKILL instead.\n', + ); + }); + + testWithoutContext('falls back to a warning if SIGKILL did not work', () async { + final BufferLogger logger = BufferLogger.test(); + final FakeAsync fakeAsync = FakeAsync(); + + fakeAsync.run((_) { + () async { + final FakeChromeConnection chromeConnection = FakeChromeConnection(maxRetries: 4); + final ChromiumLauncher chromiumLauncher = ChromiumLauncher( + fileSystem: fileSystem, + platform: platform, + processManager: processManager, + operatingSystemUtils: operatingSystemUtils, + browserFinder: findChromeExecutable, + logger: logger, + ); + + final FakeProcess process = FakeProcess( + duration: const Duration(seconds: 20), + ); + + final Chromium chrome = Chromium(0, chromeConnection, chromiumLauncher: chromiumLauncher, process: process, logger: logger); + + final Future closeFuture = chrome.close(); + fakeAsync.elapse(const Duration(seconds: 30)); + await closeFuture; + expect(process.signals, [io.ProcessSignal.sigterm, io.ProcessSignal.sigkill]); + }(); + }); + + fakeAsync.flushTimers(); + expect( + logger.warningText, + 'Failed to exit Chromium (pid: 1234) using SIGTERM. Will try sending SIGKILL instead.\n' + 'Failed to exit Chromium (pid: 1234) using SIGKILL. Giving up. Will continue, assuming ' + 'Chromium has exited successfully, but it is possible that this left a dangling Chromium ' + 'process running on the system.\n', + ); + }); + testWithoutContext('does not crash if saving profile information fails due to a file system exception.', () async { final BufferLogger logger = BufferLogger.test(); chromeLauncher = ChromiumLauncher( @@ -656,7 +768,8 @@ void main() { browserFinder: findChromeExecutable, logger: logger, ); - final Chromium chrome = Chromium(0, chromeConnection, chromiumLauncher: chromiumLauncher); + final FakeProcess process = FakeProcess(); + final Chromium chrome = Chromium(0, chromeConnection, chromiumLauncher: chromiumLauncher, process: process, logger: logger); expect(await chromiumLauncher.connect(chrome, false), equals(chrome)); expect(logger.errorText, isEmpty); }); @@ -672,7 +785,8 @@ void main() { browserFinder: findChromeExecutable, logger: logger, ); - final Chromium chrome = Chromium(0, chromeConnection, chromiumLauncher: chromiumLauncher); + final FakeProcess process = FakeProcess(); + final Chromium chrome = Chromium(0, chromeConnection, chromiumLauncher: chromiumLauncher, process: process, logger: logger); await expectToolExitLater( chromiumLauncher.connect(chrome, false), allOf( diff --git a/packages/flutter_web_plugins/pubspec.yaml b/packages/flutter_web_plugins/pubspec.yaml index 84cb9643140f0..d5d79127180a1 100644 --- a/packages/flutter_web_plugins/pubspec.yaml +++ b/packages/flutter_web_plugins/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -33,4 +33,4 @@ dev_dependencies: term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: 0c69 +# PUBSPEC CHECKSUM: 176a diff --git a/packages/integration_test/example/pubspec.yaml b/packages/integration_test/example/pubspec.yaml index d4de3e98957b2..ce9fe6db8ba68 100644 --- a/packages/integration_test/example/pubspec.yaml +++ b/packages/integration_test/example/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: flutter_test: @@ -77,11 +77,11 @@ dev_dependencies: vm_service: 11.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: uses-material-design: true -# PUBSPEC CHECKSUM: fb27 +# PUBSPEC CHECKSUM: 0b29 diff --git a/packages/integration_test/integration_test_macos/pubspec.yaml b/packages/integration_test/integration_test_macos/pubspec.yaml index d9501f40dd625..764e951d08f42 100644 --- a/packages/integration_test/integration_test_macos/pubspec.yaml +++ b/packages/integration_test/integration_test_macos/pubspec.yaml @@ -21,9 +21,9 @@ dependencies: material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dev_dependencies: pedantic: 1.11.1 -# PUBSPEC CHECKSUM: 68ab +# PUBSPEC CHECKSUM: 73ac diff --git a/packages/integration_test/pubspec.yaml b/packages/integration_test/pubspec.yaml index f9dbd36e2a7db..b4b1943d3a262 100644 --- a/packages/integration_test/pubspec.yaml +++ b/packages/integration_test/pubspec.yaml @@ -33,8 +33,8 @@ dependencies: term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - web: 0.2.1-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + web: 0.2.2-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" flutter: plugin: @@ -45,4 +45,4 @@ flutter: ios: pluginClass: IntegrationTestPlugin -# PUBSPEC CHECKSUM: e584 +# PUBSPEC CHECKSUM: 1286