From 1dc14cf960a39ce9bf27dda79afeda5554fe3644 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 17 May 2022 18:37:11 -0700 Subject: [PATCH 01/18] [google_maps_flutter_web] Remove custom analysis_options.yaml --- .../google_maps_flutter_web/analysis_options.yaml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 packages/google_maps_flutter/google_maps_flutter_web/analysis_options.yaml diff --git a/packages/google_maps_flutter/google_maps_flutter_web/analysis_options.yaml b/packages/google_maps_flutter/google_maps_flutter_web/analysis_options.yaml deleted file mode 100644 index 5aeb4e7c5e21..000000000000 --- a/packages/google_maps_flutter/google_maps_flutter_web/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: ../../../analysis_options_legacy.yaml From 4aeccc5f3186f9dfc6736cbade0e2027c05f84d1 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 17 May 2022 18:37:27 -0700 Subject: [PATCH 02/18] Bring ui shim to compliance --- .../lib/src/shims/dart_ui.dart | 2 +- .../lib/src/shims/dart_ui_fake.dart | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui.dart index 5eacec5fe867..2b254a95b951 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui.dart @@ -5,6 +5,6 @@ /// This file shims dart:ui in web-only scenarios, getting rid of the need to /// suppress analyzer warnings. -// TODO(flutter/flutter#55000) Remove this file once web-only dart:ui APIs +// TODO(ditman): Remove this file once web-only dart:ui APIs, https://github.com/flutter/flutter/issues/55000 // are exposed from a dedicated place. export 'dart_ui_fake.dart' if (dart.library.html) 'dart_ui_real.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_fake.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_fake.dart index f2862af8b704..8757ca22be17 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_fake.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/shims/dart_ui_fake.dart @@ -7,13 +7,18 @@ import 'dart:html' as html; // Fake interface for the logic that this package needs from (web-only) dart:ui. // This is conditionally exported so the analyzer sees these methods as available. +// ignore_for_file: avoid_classes_with_only_static_members +// ignore_for_file: camel_case_types + /// Shim for web_ui engine.PlatformViewRegistry /// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/ui.dart#L62 class platformViewRegistry { /// Shim for registerViewFactory /// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/ui.dart#L72 - static registerViewFactory( - String viewTypeId, html.Element Function(int viewId) viewFactory) {} + static bool registerViewFactory( + String viewTypeId, html.Element Function(int viewId) viewFactory) { + return false; + } } /// Shim for web_ui engine.AssetManager. @@ -21,7 +26,7 @@ class platformViewRegistry { class webOnlyAssetManager { /// Shim for getAssetUrl. /// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/src/engine/assets.dart#L45 - static getAssetUrl(String asset) {} + static String getAssetUrl(String asset) => ''; } /// Signature of callbacks that have no arguments and return no data. From 9bf694e0054dd3e974ce82b310a575949c1f22b1 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 17 May 2022 18:37:40 -0700 Subject: [PATCH 03/18] Fix to_screen_location types --- .../to_screen_location/to_screen_location.dart | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/third_party/to_screen_location/to_screen_location.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/third_party/to_screen_location/to_screen_location.dart index 2963111fdcc3..fc25b18b43ec 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/third_party/to_screen_location/to_screen_location.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/third_party/to_screen_location/to_screen_location.dart @@ -29,9 +29,9 @@ import 'package:google_maps/google_maps.dart' as gmaps; /// /// See: https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/Projection#public-point-toscreenlocation-latlng-location gmaps.Point toScreenLocation(gmaps.GMap map, gmaps.LatLng coords) { - final zoom = map.zoom; - final bounds = map.bounds; - final projection = map.projection; + final num? zoom = map.zoom; + final gmaps.LatLngBounds? bounds = map.bounds; + final gmaps.Projection? projection = map.projection; assert( bounds != null, 'Map Bounds required to compute screen x/y of LatLng.'); @@ -40,15 +40,15 @@ gmaps.Point toScreenLocation(gmaps.GMap map, gmaps.LatLng coords) { assert(zoom != null, 'Current map zoom level required to compute screen x/y of LatLng.'); - final ne = bounds!.northEast; - final sw = bounds.southWest; + final gmaps.LatLng ne = bounds!.northEast; + final gmaps.LatLng sw = bounds.southWest; - final topRight = projection!.fromLatLngToPoint!(ne)!; - final bottomLeft = projection.fromLatLngToPoint!(sw)!; + final gmaps.Point topRight = projection!.fromLatLngToPoint!(ne)!; + final gmaps.Point bottomLeft = projection.fromLatLngToPoint!(sw)!; - final scale = 1 << (zoom!.toInt()); // 2 ^ zoom + final int scale = 1 << (zoom!.toInt()); // 2 ^ zoom - final worldPoint = projection.fromLatLngToPoint!(coords)!; + final gmaps.Point worldPoint = projection.fromLatLngToPoint!(coords)!; return gmaps.Point( ((worldPoint.x! - bottomLeft.x!) * scale).toInt(), From 5affe351d0c92d172a4d1a06a40d28fe5496feaa Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 17 May 2022 18:40:39 -0700 Subject: [PATCH 04/18] directives_ordering --- .../lib/google_maps_flutter_web.dart | 29 +++++++++---------- .../lib/src/types.dart | 2 +- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart index c3079dc2492d..7ae646687f19 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart @@ -5,36 +5,33 @@ library google_maps_flutter_web; import 'dart:async'; +import 'dart:convert'; import 'dart:html'; import 'dart:js_util'; -import 'src/shims/dart_ui.dart' as ui; // Conditionally imports dart:ui in web -import 'dart:convert'; -import 'package:flutter/widgets.dart'; -import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; import 'package:flutter/gestures.dart'; - -import 'package:sanitize_html/sanitize_html.dart'; - -import 'package:stream_transform/stream_transform.dart'; - -import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:google_maps/google_maps.dart' as gmaps; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; +import 'package:sanitize_html/sanitize_html.dart'; +import 'package:stream_transform/stream_transform.dart'; +import 'src/shims/dart_ui.dart' as ui; // Conditionally imports dart:ui in web import 'src/third_party/to_screen_location/to_screen_location.dart'; import 'src/types.dart'; -part 'src/google_maps_flutter_web.dart'; -part 'src/google_maps_controller.dart'; part 'src/circle.dart'; part 'src/circles.dart'; +part 'src/convert.dart'; +part 'src/google_maps_controller.dart'; +part 'src/google_maps_flutter_web.dart'; +part 'src/marker.dart'; +part 'src/markers.dart'; part 'src/polygon.dart'; part 'src/polygons.dart'; part 'src/polyline.dart'; part 'src/polylines.dart'; -part 'src/marker.dart'; -part 'src/markers.dart'; -part 'src/convert.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart index ff980eb4c34b..84c66264db7b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/types.dart @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; import 'package:google_maps/google_maps.dart' as gmaps; +import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; /// A void function that handles a [gmaps.LatLng] as a parameter. /// From 8493c0a0c0fecfe819966d336f1de48f3fd048f6 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 17 May 2022 19:18:58 -0700 Subject: [PATCH 05/18] Fix geometry classes --- .../lib/src/circle.dart | 8 +-- .../lib/src/circles.dart | 46 ++++++++--------- .../lib/src/marker.dart | 24 ++++----- .../lib/src/markers.dart | 50 +++++++++---------- .../lib/src/polygon.dart | 10 ++-- .../lib/src/polygons.dart | 46 ++++++++--------- .../lib/src/polyline.dart | 10 ++-- .../lib/src/polylines.dart | 46 ++++++++--------- 8 files changed, 117 insertions(+), 123 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart index 65057d8c869e..9cd3ba1c079c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circle.dart @@ -6,10 +6,6 @@ part of google_maps_flutter_web; /// The `CircleController` class wraps a [gmaps.Circle] and its `onTap` behavior. class CircleController { - gmaps.Circle? _circle; - - final bool _consumeTapEvents; - /// Creates a `CircleController`, which wraps a [gmaps.Circle] object and its `onTap` behavior. CircleController({ required gmaps.Circle circle, @@ -24,6 +20,10 @@ class CircleController { } } + gmaps.Circle? _circle; + + final bool _consumeTapEvents; + /// Returns the wrapped [gmaps.Circle]. Only used for testing. @visibleForTesting gmaps.Circle? get circle => _circle; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart index ae8faa038ea6..7ad12ddecdae 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart @@ -6,17 +6,17 @@ part of google_maps_flutter_web; /// This class manages all the [CircleController]s associated to a [GoogleMapController]. class CirclesController extends GeometryController { + /// Initialize the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. + CirclesController({ + required StreamController> stream, + }) : _streamController = stream, + _circleIdToController = {}; + // A cache of [CircleController]s indexed by their [CircleId]. final Map _circleIdToController; // The stream over which circles broadcast their events - StreamController _streamController; - - /// Initialize the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. - CirclesController({ - required StreamController stream, - }) : _streamController = stream, - _circleIdToController = Map(); + final StreamController> _streamController; /// Returns the cache of [CircleController]s. Test only. @visibleForTesting @@ -26,9 +26,7 @@ class CirclesController extends GeometryController { /// /// Wraps each [Circle] into its corresponding [CircleController]. void addCircles(Set circlesToAdd) { - circlesToAdd.forEach((circle) { - _addCircle(circle); - }); + circlesToAdd.forEach(_addCircle); } void _addCircle(Circle circle) { @@ -36,10 +34,10 @@ class CirclesController extends GeometryController { return; } - final populationOptions = _circleOptionsFromCircle(circle); - gmaps.Circle gmCircle = gmaps.Circle(populationOptions); - gmCircle.map = googleMap; - CircleController controller = CircleController( + final gmaps.CircleOptions circleOptions = _circleOptionsFromCircle(circle); + final gmaps.Circle gmCircle = gmaps.Circle(circleOptions) + ..map = googleMap; + final CircleController controller = CircleController( circle: gmCircle, consumeTapEvents: circle.consumeTapEvents, onTap: () { @@ -50,24 +48,24 @@ class CirclesController extends GeometryController { /// Updates a set of [Circle] objects with new options. void changeCircles(Set circlesToChange) { - circlesToChange.forEach((circleToChange) { - _changeCircle(circleToChange); - }); + circlesToChange.forEach(_changeCircle); } void _changeCircle(Circle circle) { - final circleController = _circleIdToController[circle.circleId]; + final CircleController? circleController = _circleIdToController[circle.circleId]; circleController?.update(_circleOptionsFromCircle(circle)); } /// Removes a set of [CircleId]s from the cache. void removeCircles(Set circleIdsToRemove) { - circleIdsToRemove.forEach((circleId) { - final CircleController? circleController = - _circleIdToController[circleId]; - circleController?.remove(); - _circleIdToController.remove(circleId); - }); + circleIdsToRemove.forEach(_removeCircle); + } + + // Removes a circle and its controller by its [CircleId]. + void _removeCircle(CircleId circleId) { + final CircleController? circleController = _circleIdToController[circleId]; + circleController?.remove(); + _circleIdToController.remove(circleId); } // Handles the global onCircleTap function to funnel events from circles into the stream. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart index c4cd40f43323..9d607e9bbc6a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/marker.dart @@ -6,14 +6,6 @@ part of google_maps_flutter_web; /// The `MarkerController` class wraps a [gmaps.Marker], how it handles events, and its associated (optional) [gmaps.InfoWindow] widget. class MarkerController { - gmaps.Marker? _marker; - - final bool _consumeTapEvents; - - final gmaps.InfoWindow? _infoWindow; - - bool _infoWindowShown = false; - /// Creates a `MarkerController`, which wraps a [gmaps.Marker] object, its `onTap`/`onDrag` behavior, and its associated [gmaps.InfoWindow]. MarkerController({ required gmaps.Marker marker, @@ -27,12 +19,12 @@ class MarkerController { _infoWindow = infoWindow, _consumeTapEvents = consumeTapEvents { if (onTap != null) { - marker.onClick.listen((event) { + marker.onClick.listen((gmaps.MapMouseEvent event) { onTap.call(); }); } if (onDragStart != null) { - marker.onDragstart.listen((event) { + marker.onDragstart.listen((gmaps.MapMouseEvent event) { if (marker != null) { marker.position = event.latLng; } @@ -40,7 +32,7 @@ class MarkerController { }); } if (onDrag != null) { - marker.onDrag.listen((event) { + marker.onDrag.listen((gmaps.MapMouseEvent event) { if (marker != null) { marker.position = event.latLng; } @@ -48,7 +40,7 @@ class MarkerController { }); } if (onDragEnd != null) { - marker.onDragend.listen((event) { + marker.onDragend.listen((gmaps.MapMouseEvent event) { if (marker != null) { marker.position = event.latLng; } @@ -57,6 +49,14 @@ class MarkerController { } } + gmaps.Marker? _marker; + + final bool _consumeTapEvents; + + final gmaps.InfoWindow? _infoWindow; + + bool _infoWindowShown = false; + /// Returns `true` if this Controller will use its own `onTap` handler to consume events. bool get consumeTapEvents => _consumeTapEvents; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart index 542a48bcb707..22b5acd85cd1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart @@ -6,17 +6,17 @@ part of google_maps_flutter_web; /// This class manages a set of [MarkerController]s associated to a [GoogleMapController]. class MarkersController extends GeometryController { + /// Initialize the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. + MarkersController({ + required StreamController> stream, + }) : _streamController = stream, + _markerIdToController = {}; + // A cache of [MarkerController]s indexed by their [MarkerId]. final Map _markerIdToController; // The stream over which markers broadcast their events - StreamController _streamController; - - /// Initialize the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. - MarkersController({ - required StreamController stream, - }) : _streamController = stream, - _markerIdToController = Map(); + final StreamController> _streamController; /// Returns the cache of [MarkerController]s. Test only. @visibleForTesting @@ -34,32 +34,32 @@ class MarkersController extends GeometryController { return; } - final infoWindowOptions = _infoWindowOptionsFromMarker(marker); + final gmaps.InfoWindowOptions? infoWindowOptions = _infoWindowOptionsFromMarker(marker); gmaps.InfoWindow? gmInfoWindow; if (infoWindowOptions != null) { gmInfoWindow = gmaps.InfoWindow(infoWindowOptions); // Google Maps' JS SDK does not have a click event on the InfoWindow, so // we make one... - if (infoWindowOptions.content is HtmlElement) { - final content = infoWindowOptions.content as HtmlElement; + if (infoWindowOptions.content != null && infoWindowOptions.content is HtmlElement) { + final HtmlElement content = infoWindowOptions.content! as HtmlElement; content.onClick.listen((_) { _onInfoWindowTap(marker.markerId); }); } } - final currentMarker = _markerIdToController[marker.markerId]?.marker; + final gmaps.Marker? currentMarker = _markerIdToController[marker.markerId]?.marker; - final populationOptions = _markerOptionsFromMarker(marker, currentMarker); - gmaps.Marker gmMarker = gmaps.Marker(populationOptions); - gmMarker.map = googleMap; - MarkerController controller = MarkerController( + final gmaps.MarkerOptions markerOptions = _markerOptionsFromMarker(marker, currentMarker); + final gmaps.Marker gmMarker = gmaps.Marker(markerOptions) + ..map = googleMap; + final MarkerController controller = MarkerController( marker: gmMarker, infoWindow: gmInfoWindow, consumeTapEvents: marker.consumeTapEvents, onTap: () { - this.showMarkerInfoWindow(marker.markerId); + showMarkerInfoWindow(marker.markerId); _onMarkerTap(marker.markerId); }, onDragStart: (gmaps.LatLng latLng) { @@ -81,13 +81,13 @@ class MarkersController extends GeometryController { } void _changeMarker(Marker marker) { - MarkerController? markerController = _markerIdToController[marker.markerId]; + final MarkerController? markerController = _markerIdToController[marker.markerId]; if (markerController != null) { - final markerOptions = _markerOptionsFromMarker( + final gmaps.MarkerOptions markerOptions = _markerOptionsFromMarker( marker, markerController.marker, ); - final infoWindow = _infoWindowOptionsFromMarker(marker); + final gmaps.InfoWindowOptions? infoWindow = _infoWindowOptionsFromMarker(marker); markerController.update( markerOptions, newInfoWindowContent: infoWindow?.content as HtmlElement?, @@ -113,7 +113,7 @@ class MarkersController extends GeometryController { /// See also [hideMarkerInfoWindow] and [isInfoWindowShown]. void showMarkerInfoWindow(MarkerId markerId) { _hideAllMarkerInfoWindow(); - MarkerController? markerController = _markerIdToController[markerId]; + final MarkerController? markerController = _markerIdToController[markerId]; markerController?.showInfoWindow(); } @@ -121,7 +121,7 @@ class MarkersController extends GeometryController { /// /// See also [showMarkerInfoWindow] and [isInfoWindowShown]. void hideMarkerInfoWindow(MarkerId markerId) { - MarkerController? markerController = _markerIdToController[markerId]; + final MarkerController? markerController = _markerIdToController[markerId]; markerController?.hideInfoWindow(); } @@ -129,7 +129,7 @@ class MarkersController extends GeometryController { /// /// See also [showMarkerInfoWindow] and [hideMarkerInfoWindow]. bool isInfoWindowShown(MarkerId markerId) { - MarkerController? markerController = _markerIdToController[markerId]; + final MarkerController? markerController = _markerIdToController[markerId]; return markerController?.infoWindowShown ?? false; } @@ -172,8 +172,8 @@ class MarkersController extends GeometryController { void _hideAllMarkerInfoWindow() { _markerIdToController.values - .where((controller) => - controller == null ? false : controller.infoWindowShown) - .forEach((controller) => controller.hideInfoWindow()); + .where((MarkerController? controller) => + controller?.infoWindowShown ?? false) + .forEach((MarkerController controller) => controller.hideInfoWindow()); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart index 9921d2ff3876..719eeeecdb43 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygon.dart @@ -6,10 +6,6 @@ part of google_maps_flutter_web; /// The `PolygonController` class wraps a [gmaps.Polygon] and its `onTap` behavior. class PolygonController { - gmaps.Polygon? _polygon; - - final bool _consumeTapEvents; - /// Creates a `PolygonController` that wraps a [gmaps.Polygon] object and its `onTap` behavior. PolygonController({ required gmaps.Polygon polygon, @@ -18,12 +14,16 @@ class PolygonController { }) : _polygon = polygon, _consumeTapEvents = consumeTapEvents { if (onTap != null) { - polygon.onClick.listen((event) { + polygon.onClick.listen((gmaps.PolyMouseEvent event) { onTap.call(); }); } } + gmaps.Polygon? _polygon; + + final bool _consumeTapEvents; + /// Returns the wrapped [gmaps.Polygon]. Only used for testing. @visibleForTesting gmaps.Polygon? get polygon => _polygon; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart index 8a9643156351..d52aa62c718c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart @@ -6,17 +6,17 @@ part of google_maps_flutter_web; /// This class manages a set of [PolygonController]s associated to a [GoogleMapController]. class PolygonsController extends GeometryController { + /// Initializes the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. + PolygonsController({ + required StreamController> stream, + }) : _streamController = stream, + _polygonIdToController = {}; + // A cache of [PolygonController]s indexed by their [PolygonId]. final Map _polygonIdToController; // The stream over which polygons broadcast events - StreamController _streamController; - - /// Initializes the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. - PolygonsController({ - required StreamController stream, - }) : _streamController = stream, - _polygonIdToController = Map(); + final StreamController> _streamController; /// Returns the cache of [PolygonController]s. Test only. @visibleForTesting @@ -27,9 +27,7 @@ class PolygonsController extends GeometryController { /// Wraps each Polygon into its corresponding [PolygonController]. void addPolygons(Set polygonsToAdd) { if (polygonsToAdd != null) { - polygonsToAdd.forEach((polygon) { - _addPolygon(polygon); - }); + polygonsToAdd.forEach(_addPolygon); } } @@ -38,10 +36,10 @@ class PolygonsController extends GeometryController { return; } - final populationOptions = _polygonOptionsFromPolygon(googleMap, polygon); - gmaps.Polygon gmPolygon = gmaps.Polygon(populationOptions); - gmPolygon.map = googleMap; - PolygonController controller = PolygonController( + final gmaps.PolygonOptions polygonOptions = _polygonOptionsFromPolygon(googleMap, polygon); + final gmaps.Polygon gmPolygon = gmaps.Polygon(polygonOptions) + ..map = googleMap; + final PolygonController controller = PolygonController( polygon: gmPolygon, consumeTapEvents: polygon.consumeTapEvents, onTap: () { @@ -53,26 +51,26 @@ class PolygonsController extends GeometryController { /// Updates a set of [Polygon] objects with new options. void changePolygons(Set polygonsToChange) { if (polygonsToChange != null) { - polygonsToChange.forEach((polygonToChange) { - _changePolygon(polygonToChange); - }); + polygonsToChange.forEach(_changePolygon); } } void _changePolygon(Polygon polygon) { - PolygonController? polygonController = + final PolygonController? polygonController = _polygonIdToController[polygon.polygonId]; polygonController?.update(_polygonOptionsFromPolygon(googleMap, polygon)); } /// Removes a set of [PolygonId]s from the cache. void removePolygons(Set polygonIdsToRemove) { - polygonIdsToRemove.forEach((polygonId) { - final PolygonController? polygonController = - _polygonIdToController[polygonId]; - polygonController?.remove(); - _polygonIdToController.remove(polygonId); - }); + polygonIdsToRemove.forEach(_removePolygon); + } + + // Removes a polygon and its controller by its [PolygonId]. + void _removePolygon(PolygonId polygonId) { + final PolygonController? polygonController = _polygonIdToController[polygonId]; + polygonController?.remove(); + _polygonIdToController.remove(polygonId); } // Handle internal events diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart index eb4b6d88b503..428bb7fce016 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polyline.dart @@ -6,10 +6,6 @@ part of google_maps_flutter_web; /// The `PolygonController` class wraps a [gmaps.Polyline] and its `onTap` behavior. class PolylineController { - gmaps.Polyline? _polyline; - - final bool _consumeTapEvents; - /// Creates a `PolylineController` that wraps a [gmaps.Polyline] object and its `onTap` behavior. PolylineController({ required gmaps.Polyline polyline, @@ -18,12 +14,16 @@ class PolylineController { }) : _polyline = polyline, _consumeTapEvents = consumeTapEvents { if (onTap != null) { - polyline.onClick.listen((event) { + polyline.onClick.listen((gmaps.PolyMouseEvent event) { onTap.call(); }); } } + gmaps.Polyline? _polyline; + + final bool _consumeTapEvents; + /// Returns the wrapped [gmaps.Polyline]. Only used for testing. @visibleForTesting gmaps.Polyline? get line => _polyline; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart index 695b29554c04..4706c438ef36 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart @@ -6,17 +6,17 @@ part of google_maps_flutter_web; /// This class manages a set of [PolylinesController]s associated to a [GoogleMapController]. class PolylinesController extends GeometryController { + /// Initializes the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. + PolylinesController({ + required StreamController> stream, + }) : _streamController = stream, + _polylineIdToController = {}; + // A cache of [PolylineController]s indexed by their [PolylineId]. final Map _polylineIdToController; // The stream over which polylines broadcast their events - StreamController _streamController; - - /// Initializes the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. - PolylinesController({ - required StreamController stream, - }) : _streamController = stream, - _polylineIdToController = Map(); + final StreamController> _streamController; /// Returns the cache of [PolylineContrller]s. Test only. @visibleForTesting @@ -26,9 +26,7 @@ class PolylinesController extends GeometryController { /// /// Wraps each line into its corresponding [PolylineController]. void addPolylines(Set polylinesToAdd) { - polylinesToAdd.forEach((polyline) { - _addPolyline(polyline); - }); + polylinesToAdd.forEach(_addPolyline); } void _addPolyline(Polyline polyline) { @@ -36,10 +34,10 @@ class PolylinesController extends GeometryController { return; } - final polylineOptions = _polylineOptionsFromPolyline(googleMap, polyline); - gmaps.Polyline gmPolyline = gmaps.Polyline(polylineOptions); - gmPolyline.map = googleMap; - PolylineController controller = PolylineController( + final gmaps.PolylineOptions polylineOptions = _polylineOptionsFromPolyline(googleMap, polyline); + final gmaps.Polyline gmPolyline = gmaps.Polyline(polylineOptions) + ..map = googleMap; + final PolylineController controller = PolylineController( polyline: gmPolyline, consumeTapEvents: polyline.consumeTapEvents, onTap: () { @@ -50,13 +48,11 @@ class PolylinesController extends GeometryController { /// Updates a set of [Polyline] objects with new options. void changePolylines(Set polylinesToChange) { - polylinesToChange.forEach((polylineToChange) { - _changePolyline(polylineToChange); - }); + polylinesToChange.forEach(_changePolyline); } void _changePolyline(Polyline polyline) { - PolylineController? polylineController = + final PolylineController? polylineController = _polylineIdToController[polyline.polylineId]; polylineController ?.update(_polylineOptionsFromPolyline(googleMap, polyline)); @@ -64,12 +60,14 @@ class PolylinesController extends GeometryController { /// Removes a set of [PolylineId]s from the cache. void removePolylines(Set polylineIdsToRemove) { - polylineIdsToRemove.forEach((polylineId) { - final PolylineController? polylineController = - _polylineIdToController[polylineId]; - polylineController?.remove(); - _polylineIdToController.remove(polylineId); - }); + polylineIdsToRemove.forEach(_removePolyline); + } + + // Removes a polyline and its controller by its [PolylineId]. + void _removePolyline(PolylineId polylineId) { + final PolylineController? polylineController = _polylineIdToController[polylineId]; + polylineController?.remove(); + _polylineIdToController.remove(polylineId); } // Handle internal events From 5073b3cbf8921385ce2352e88f1ce0a82f81ad7e Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 18 May 2022 12:08:28 -0700 Subject: [PATCH 06/18] Fix controller + plugin (removes unused fields from controller constructor) --- .../lib/src/google_maps_controller.dart | 136 +++++++++--------- .../lib/src/google_maps_flutter_web.dart | 21 +-- 2 files changed, 79 insertions(+), 78 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index edf47764f346..be356223958e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -11,6 +11,43 @@ typedef DebugCreateMapFunction = gmaps.GMap Function( /// Encapsulates a [gmaps.GMap], its events, and where in the DOM it's rendered. class GoogleMapController { + /// Initializes the GMap, and the sub-controllers related to it. Wires events. + GoogleMapController({ + required int mapId, + required StreamController> streamController, + required CameraPosition initialCameraPosition, + Set markers = const {}, + Set polygons = const {}, + Set polylines = const {}, + Set circles = const {}, + Map mapOptions = const {}, + }) : _mapId = mapId, + _streamController = streamController, + _initialCameraPosition = initialCameraPosition, + _markers = markers, + _polygons = polygons, + _polylines = polylines, + _circles = circles, + _rawMapOptions = mapOptions { + _circlesController = CirclesController(stream: _streamController); + _polygonsController = PolygonsController(stream: _streamController); + _polylinesController = PolylinesController(stream: _streamController); + _markersController = MarkersController(stream: _streamController); + + // Register the view factory that will hold the `_div` that holds the map in the DOM. + // The `_div` needs to be created outside of the ViewFactory (and cached!) so we can + // use it to create the [gmaps.GMap] in the `init()` method of this class. + _div = DivElement() + ..id = _getViewType(mapId) + ..style.width = '100%' + ..style.height = '100%'; + + ui.platformViewRegistry.registerViewFactory( + _getViewType(mapId), + (int viewId) => _div, + ); + } + // The internal ID of the map. Used to broadcast events, DOM IDs and everything where a unique ID is needed. final int _mapId; @@ -51,14 +88,14 @@ class GoogleMapController { gmaps.GMap? _googleMap; // The StreamController used by this controller and the geometry ones. - final StreamController _streamController; + final StreamController> _streamController; /// The StreamController for the events of this Map. Only for integration testing. @visibleForTesting - StreamController get stream => _streamController; + StreamController> get stream => _streamController; /// The Stream over which this controller broadcasts events. - Stream get events => _streamController.stream; + Stream> get events => _streamController.stream; // Geometry controllers, for different features of the map. CirclesController? _circlesController; @@ -71,46 +108,6 @@ class GoogleMapController { // Keeps track if the map is moving or not. bool _mapIsMoving = false; - /// Initializes the GMap, and the sub-controllers related to it. Wires events. - GoogleMapController({ - required int mapId, - required StreamController streamController, - required CameraPosition initialCameraPosition, - Set markers = const {}, - Set polygons = const {}, - Set polylines = const {}, - Set circles = const {}, - Set tileOverlays = const {}, - Set> gestureRecognizers = - const >{}, - Map mapOptions = const {}, - }) : _mapId = mapId, - _streamController = streamController, - _initialCameraPosition = initialCameraPosition, - _markers = markers, - _polygons = polygons, - _polylines = polylines, - _circles = circles, - _rawMapOptions = mapOptions { - _circlesController = CirclesController(stream: this._streamController); - _polygonsController = PolygonsController(stream: this._streamController); - _polylinesController = PolylinesController(stream: this._streamController); - _markersController = MarkersController(stream: this._streamController); - - // Register the view factory that will hold the `_div` that holds the map in the DOM. - // The `_div` needs to be created outside of the ViewFactory (and cached!) so we can - // use it to create the [gmaps.GMap] in the `init()` method of this class. - _div = DivElement() - ..id = _getViewType(mapId) - ..style.width = '100%' - ..style.height = '100%'; - - ui.platformViewRegistry.registerViewFactory( - _getViewType(mapId), - (int viewId) => _div, - ); - } - /// Overrides certain properties to install mocks defined during testing. @visibleForTesting void debugSetOverrides({ @@ -161,12 +158,12 @@ class GoogleMapController { /// Failure to call this method would result in the GMap not rendering at all, /// and most of the public methods on this class no-op'ing. void init() { - var options = _rawOptionsToGmapsOptions(_rawMapOptions); + gmaps.MapOptions options = _rawOptionsToGmapsOptions(_rawMapOptions); // Initial position can only to be set here! options = _applyInitialPosition(_initialCameraPosition, options); // Create the map... - final map = _createMap(_div, options); + final gmaps.GMap map = _createMap(_div, options); _googleMap = map; _attachMapEvents(map); @@ -185,34 +182,34 @@ class GoogleMapController { // Funnels map gmap events into the plugin's stream controller. void _attachMapEvents(gmaps.GMap map) { - map.onTilesloaded.first.then((event) { + map.onTilesloaded.first.then((void _) { // Report the map as ready to go the first time the tiles load _streamController.add(WebMapReadyEvent(_mapId)); }); - map.onClick.listen((event) { + map.onClick.listen((gmaps.IconMouseEvent event) { assert(event.latLng != null); _streamController.add( - MapTapEvent(_mapId, _gmLatLngToLatLng(event.latLng!)), + MapTapEvent(_mapId, _gmLatLngToLatLng(event.latLng!)) as MapEvent, ); }); - map.onRightclick.listen((event) { + map.onRightclick.listen((gmaps.MapMouseEvent event) { assert(event.latLng != null); _streamController.add( - MapLongPressEvent(_mapId, _gmLatLngToLatLng(event.latLng!)), + MapLongPressEvent(_mapId, _gmLatLngToLatLng(event.latLng!)) as MapEvent, ); }); - map.onBoundsChanged.listen((event) { + map.onBoundsChanged.listen((void _) { if (!_mapIsMoving) { _mapIsMoving = true; - _streamController.add(CameraMoveStartedEvent(_mapId)); + _streamController.add(CameraMoveStartedEvent(_mapId) as MapEvent); } _streamController.add( CameraMoveEvent(_mapId, _gmViewportToCameraPosition(map)), ); }); - map.onIdle.listen((event) { + map.onIdle.listen((void _) { _mapIsMoving = false; - _streamController.add(CameraIdleEvent(_mapId)); + _streamController.add(CameraIdleEvent(_mapId) as MapEvent); }); } @@ -243,15 +240,15 @@ class GoogleMapController { // Renders the initial sets of geometry. void _renderInitialGeometry({ - Set markers = const {}, - Set circles = const {}, - Set polygons = const {}, - Set polylines = const {}, + Set markers = const {}, + Set circles = const {}, + Set polygons = const {}, + Set polylines = const {}, }) { assert( _controllersBoundToMap, - 'Geometry controllers must be bound to a map before any geometry can ' + - 'be added to them. Ensure _attachGeometryControllers is called first.'); + 'Geometry controllers must be bound to a map before any geometry can ' + 'be added to them. Ensure _attachGeometryControllers is called first.'); // The above assert will only succeed if the controllers have been bound to a map // in the [_attachGeometryControllers] method, which ensures that all these @@ -280,13 +277,14 @@ class GoogleMapController { void updateRawOptions(Map optionsUpdate) { assert(_googleMap != null, 'Cannot update options on a null map.'); - final newOptions = _mergeRawOptions(optionsUpdate); + final Map newOptions = _mergeRawOptions(optionsUpdate); _setOptions(_rawOptionsToGmapsOptions(newOptions)); _setTrafficLayer(_googleMap!, _isTrafficLayerEnabled(newOptions)); } // Sets new [gmaps.MapOptions] on the wrapped map. + // ignore: use_setters_to_change_properties void _setOptions(gmaps.MapOptions options) { _googleMap?.options = options; } @@ -309,9 +307,11 @@ class GoogleMapController { Future getVisibleRegion() async { assert(_googleMap != null, 'Cannot get the visible region of a null map.'); - return _gmLatLngBoundsTolatLngBounds( - await _googleMap!.bounds ?? _nullGmapsLatLngBounds, - ); + final gmaps.LatLngBounds bounds = + await Future.value(_googleMap!.bounds) + ?? _nullGmapsLatLngBounds; + + return _gmLatLngBoundsTolatLngBounds(bounds); } /// Returns the [ScreenCoordinate] for a given viewport [LatLng]. @@ -319,7 +319,7 @@ class GoogleMapController { assert(_googleMap != null, 'Cannot get the screen coordinates with a null map.'); - final point = toScreenLocation(_googleMap!, _latLngToGmLatLng(latLng)); + final gmaps.Point point = toScreenLocation(_googleMap!, _latLngToGmLatLng(latLng)); return ScreenCoordinate(x: point.x!.toInt(), y: point.y!.toInt()); } @@ -424,8 +424,8 @@ class GoogleMapController { } } -/// An event fired when a [mapId] on web is interactive. -class WebMapReadyEvent extends MapEvent { +/// A MapEvent event fired when a [mapId] on web is interactive. +class WebMapReadyEvent extends MapEvent { /// Build a WebMapReady Event for the map represented by `mapId`. - WebMapReadyEvent(int mapId) : super(mapId, null); + WebMapReadyEvent(int mapId) : super(mapId, mapId); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart index 47bfdc7bba15..c076ecf25269 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart @@ -14,23 +14,24 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { } // A cache of map controllers by map Id. - Map _mapById = Map(); + Map _mapById = {}; /// Allows tests to inject controllers without going through the buildView flow. @visibleForTesting + // ignore: use_setters_to_change_properties void debugSetMapById(Map mapById) { _mapById = mapById; } // Convenience getter for a stream of events filtered by their mapId. - Stream _events(int mapId) => _map(mapId).events; + Stream> _events(int mapId) => _map(mapId).events; // Convenience getter for a map controller by its mapId. GoogleMapController _map(int mapId) { - final controller = _mapById[mapId]; + final GoogleMapController? controller = _mapById[mapId]; assert(controller != null, 'Maps cannot be retrieved before calling buildView!'); - return controller; + return controller!; } @override @@ -134,7 +135,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { String? mapStyle, { required int mapId, }) async { - _map(mapId).updateRawOptions({ + _map(mapId).updateRawOptions({ 'styles': _mapStyles(mapStyle), }); } @@ -303,13 +304,13 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { }) { // Bail fast if we've already rendered this map ID... if (_mapById[creationId]?.widget != null) { - return _mapById[creationId].widget; + return _mapById[creationId]!.widget!; } - final StreamController controller = - StreamController.broadcast(); + final StreamController> controller = + StreamController>.broadcast(); - final mapController = GoogleMapController( + final GoogleMapController mapController = GoogleMapController( initialCameraPosition: initialCameraPosition, mapId: creationId, streamController: controller, @@ -322,7 +323,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { _mapById[creationId] = mapController; - mapController.events.whereType().first.then((event) { + mapController.events.whereType().first.then((WebMapReadyEvent event) { assert(creationId == event.mapId, 'Received WebMapReadyEvent for the wrong map'); // Notify the plugin now that there's a fully initialized controller. From 79f4c102744da26e32aa606582794f386f8f70c3 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 18 May 2022 16:09:30 -0700 Subject: [PATCH 07/18] Fix convert.dart --- .../lib/src/convert.dart | 199 ++++++++++-------- 1 file changed, 110 insertions(+), 89 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index c026a03be804..cf2153acb909 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -5,17 +5,17 @@ part of google_maps_flutter_web; // Default values for when the gmaps objects return null/undefined values. -final _nullGmapsLatLng = gmaps.LatLng(0, 0); -final _nullGmapsLatLngBounds = +final gmaps.LatLng _nullGmapsLatLng = gmaps.LatLng(0, 0); +final gmaps.LatLngBounds _nullGmapsLatLngBounds = gmaps.LatLngBounds(_nullGmapsLatLng, _nullGmapsLatLng); // Defaults taken from the Google Maps Platform SDK documentation. -final _defaultCssColor = '#000000'; -final _defaultCssOpacity = 0.0; +const String _defaultCssColor = '#000000'; +const double _defaultCssOpacity = 0.0; // Indices in the plugin side don't match with the ones // in the gmaps lib. This translates from plugin -> gmaps. -final _mapTypeToMapTypeId = { +final Map _mapTypeToMapTypeId = { 0: gmaps.MapTypeId.ROADMAP, // "none" in the plugin 1: gmaps.MapTypeId.ROADMAP, 2: gmaps.MapTypeId.SATELLITE, @@ -28,7 +28,7 @@ String _getCssColor(Color color) { if (color == null) { return _defaultCssColor; } - return '#' + color.value.toRadixString(16).padLeft(8, '0').substring(2); + return '#${color.value.toRadixString(16).padLeft(8, '0').substring(2)}'; } // Extracts the opacity from a [Color]. @@ -55,17 +55,18 @@ double _getCssOpacity(Color color) { // indoorViewEnabled seems to not have an equivalent in web // buildingsEnabled seems to not have an equivalent in web // padding seems to behave differently in web than mobile. You can't move UI elements in web. -gmaps.MapOptions _rawOptionsToGmapsOptions(Map rawOptions) { - gmaps.MapOptions options = gmaps.MapOptions(); +gmaps.MapOptions _rawOptionsToGmapsOptions(Map rawOptions) { + final gmaps.MapOptions options = gmaps.MapOptions(); if (_mapTypeToMapTypeId.containsKey(rawOptions['mapType'])) { options.mapTypeId = _mapTypeToMapTypeId[rawOptions['mapType']]; } if (rawOptions['minMaxZoomPreference'] != null) { + final List minMaxPreference = rawOptions['minMaxZoomPreference']! as List; options - ..minZoom = rawOptions['minMaxZoomPreference'][0] - ..maxZoom = rawOptions['minMaxZoomPreference'][1]; + ..minZoom = minMaxPreference[0] + ..maxZoom = minMaxPreference[1]; } if (rawOptions['cameraTargetBounds'] != null) { @@ -74,11 +75,11 @@ gmaps.MapOptions _rawOptionsToGmapsOptions(Map rawOptions) { } if (rawOptions['zoomControlsEnabled'] != null) { - options.zoomControl = rawOptions['zoomControlsEnabled']; + options.zoomControl = rawOptions['zoomControlsEnabled'] as bool?; } if (rawOptions['styles'] != null) { - options.styles = rawOptions['styles']; + options.styles = rawOptions['styles'] as List?; } if (rawOptions['scrollGesturesEnabled'] == false || @@ -110,37 +111,40 @@ gmaps.MapOptions _applyInitialPosition( } // Extracts the status of the traffic layer from the rawOptions map. -bool _isTrafficLayerEnabled(Map rawOptions) { - return rawOptions['trafficEnabled'] ?? false; +bool _isTrafficLayerEnabled(Map rawOptions) { + return rawOptions['trafficEnabled'] as bool? ?? false; } // The keys we'd expect to see in a serialized MapTypeStyle JSON object. -final _mapStyleKeys = { +final Set _mapStyleKeys = { 'elementType', 'featureType', 'stylers', }; // Checks if the passed in Map contains some of the _mapStyleKeys. -bool _isJsonMapStyle(Map value) { +bool _isJsonMapStyle(Map value) { return _mapStyleKeys.intersection(value.keys.toSet()).isNotEmpty; } // Converts an incoming JSON-encoded Style info, into the correct gmaps array. List _mapStyles(String? mapStyleJson) { - List styles = []; + List styles = []; if (mapStyleJson != null) { - styles = json - .decode(mapStyleJson, reviver: (key, value) { - if (value is Map && _isJsonMapStyle(value)) { + styles = (json.decode(mapStyleJson, reviver: (Object? key, Object? value) { + if (value is Map && _isJsonMapStyle(value as Map)) { + List stylers = []; + if (value['stylers'] != null) { + stylers = (value['stylers']! as List).map((Object e) => jsify(e)).toList(); + } return gmaps.MapTypeStyle() - ..elementType = value['elementType'] - ..featureType = value['featureType'] - ..stylers = - (value['stylers'] as List).map((e) => jsify(e)).toList(); + ..elementType = value['elementType'] as String? + ..featureType = value['featureType'] as String? + ..stylers = stylers; } return value; - }) + }) as List) + .where((Object? element) => element != null) .cast() .toList(); // .toList calls are required so the JS API understands the underlying data structure. @@ -173,12 +177,12 @@ CameraPosition _gmViewportToCameraPosition(gmaps.GMap map) { } // Convert plugin objects to gmaps.Options objects -// TODO: Move to their appropriate objects, maybe make these copy constructors: +// TODO(ditman): Move to their appropriate objects, maybe make them copy constructors? // Marker.fromMarker(anotherMarker, moreOptions); gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) { - final markerTitle = marker.infoWindow.title ?? ''; - final markerSnippet = marker.infoWindow.snippet ?? ''; + final String markerTitle = marker.infoWindow.title ?? ''; + final String markerSnippet = marker.infoWindow.snippet ?? ''; // If both the title and snippet of an infowindow are empty, we don't really // want an infowindow... @@ -200,6 +204,13 @@ gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) { if (markerSnippet.isNotEmpty) { final HtmlElement snippet = DivElement() ..className = 'infowindow-snippet' + // `sanitizeHtml` is used to clean the (potential) user input from (potential) + // XSS attacks through the contents of the marker InfoWindow. + // See: https://pub.dev/documentation/sanitize_html/latest/sanitize_html/sanitizeHtml.html + // See: b/159137885, b/159598165 + // The NodeTreeSanitizer.trusted just tells setInnerHtml to leave the output + // of `sanitizeHtml` untouched. + // ignore: unsafe_html ..setInnerHtml( sanitizeHtml(markerSnippet), treeSanitizer: NodeTreeSanitizer.trusted, @@ -210,7 +221,7 @@ gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) { return gmaps.InfoWindowOptions() ..content = container ..zIndex = marker.zIndex; - // TODO: Compute the pixelOffset of the infoWindow, from the size of the Marker, + // TODO(ditman): Compute the pixelOffset of the infoWindow, from the size of the Marker, // and the marker.infoWindow.anchor property. } @@ -221,7 +232,7 @@ gmaps.MarkerOptions _markerOptionsFromMarker( Marker marker, gmaps.Marker? currentMarker, ) { - final iconConfig = marker.icon.toJson() as List; + final List iconConfig = marker.icon.toJson() as List; gmaps.Icon? icon; if (iconConfig != null) { @@ -231,19 +242,20 @@ gmaps.MarkerOptions _markerOptionsFromMarker( // already encoded in the iconConfig[1] icon = gmaps.Icon() - ..url = ui.webOnlyAssetManager.getAssetUrl(iconConfig[1]); + ..url = ui.webOnlyAssetManager.getAssetUrl(iconConfig[1] as String); // iconConfig[3] may contain the [width, height] of the image, if passed! if (iconConfig.length >= 4 && iconConfig[3] != null) { - final size = gmaps.Size(iconConfig[3][0], iconConfig[3][1]); + final List rawIconSize = iconConfig[3] as List; + final gmaps.Size size = gmaps.Size(rawIconSize[0], rawIconSize[1]); icon ..size = size ..scaledSize = size; } } else if (iconConfig[0] == 'fromBytes') { // Grab the bytes, and put them into a blob - List bytes = iconConfig[1]; - final blob = Blob([bytes]); // Let the browser figure out the encoding + final List bytes = iconConfig[1] as List; + final Blob blob = Blob([bytes]); // Let the browser figure out the encoding icon = gmaps.Icon()..url = Url.createObjectUrlFromBlob(blob); } } @@ -253,18 +265,18 @@ gmaps.MarkerOptions _markerOptionsFromMarker( marker.position.latitude, marker.position.longitude, ) - ..title = sanitizeHtml(marker.infoWindow.title ?? "") + ..title = sanitizeHtml(marker.infoWindow.title ?? '') ..zIndex = marker.zIndex ..visible = marker.visible ..opacity = marker.alpha ..draggable = marker.draggable ..icon = icon; - // TODO: Compute anchor properly, otherwise infowindows attach to the wrong spot. + // TODO(ditman): Compute anchor properly, otherwise infowindows attach to the wrong spot. // Flat and Rotation are not supported directly on the web. } gmaps.CircleOptions _circleOptionsFromCircle(Circle circle) { - final circleOptions = gmaps.CircleOptions() + final gmaps.CircleOptions circleOptions = gmaps.CircleOptions() ..strokeColor = _getCssColor(circle.strokeColor) ..strokeOpacity = _getCssOpacity(circle.strokeColor) ..strokeWeight = circle.strokeWidth @@ -279,28 +291,21 @@ gmaps.CircleOptions _circleOptionsFromCircle(Circle circle) { gmaps.PolygonOptions _polygonOptionsFromPolygon( gmaps.GMap googleMap, Polygon polygon) { - List path = []; - polygon.points.forEach((point) { - path.add(_latLngToGmLatLng(point)); - }); - final polygonDirection = _isPolygonClockwise(path); - List> paths = [path]; - int holeIndex = 0; - polygon.holes.forEach((hole) { - List holePath = - hole.map((point) => _latLngToGmLatLng(point)).toList(); - if (_isPolygonClockwise(holePath) == polygonDirection) { - holePath = holePath.reversed.toList(); - if (kDebugMode) { - print( - 'Hole [$holeIndex] in Polygon [${polygon.polygonId.value}] has been reversed.' - ' Ensure holes in polygons are "wound in the opposite direction to the outer path."' - ' More info: https://github.com/flutter/flutter/issues/74096'); - } - } - paths.add(holePath); - holeIndex++; - }); + final List path = []; + + // Convert all points to GmLatLng, then add them to the path + polygon.points.map(_latLngToGmLatLng).forEach(path.add); + + final bool isClockwisePolygon = _isPolygonClockwise(path); + + final List> paths = >[path]; + + for (int i = 0; i < polygon.holes.length; i++) { + final List hole = polygon.holes[i]; + final List correctHole = _ensureHoleHasReverseWinding(hole, isClockwisePolygon, holeId: i, polygonId: polygon.polygonId); + paths.add(correctHole); + } + return gmaps.PolygonOptions() ..paths = paths ..strokeColor = _getCssColor(polygon.strokeColor) @@ -313,6 +318,23 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon( ..geodesic = polygon.geodesic; } +List _ensureHoleHasReverseWinding(List hole, bool polyIsClockwise, {int? holeId, PolygonId? polygonId}) { + List holePath = hole.map(_latLngToGmLatLng).toList(); + final bool holeIsClockwise = _isPolygonClockwise(holePath); + + if (holeIsClockwise == polyIsClockwise) { + holePath = holePath.reversed.toList(); + if (kDebugMode) { + print( + 'Hole [$holeId] in Polygon [${polygonId?.value}] has been reversed.' + ' Ensure holes in polygons are "wound in the opposite direction to the outer path."' + ' More info: https://github.com/flutter/flutter/issues/74096'); + } + } + + return holePath; +} + /// Calculates the direction of a given Polygon /// based on: https://stackoverflow.com/a/1165943 /// @@ -325,8 +347,8 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon( /// the `path` is a transformed version of [Polygon.points] or each of the /// [Polygon.holes], guaranteeing that `lat` and `lng` can be accessed with `!`. bool _isPolygonClockwise(List path) { - var direction = 0.0; - for (var i = 0; i < path.length; i++) { + double direction = 0.0; + for (int i = 0; i < path.length; i++) { direction = direction + ((path[(i + 1) % path.length].lat - path[i].lat) * (path[(i + 1) % path.length].lng + path[i].lng)); @@ -336,10 +358,9 @@ bool _isPolygonClockwise(List path) { gmaps.PolylineOptions _polylineOptionsFromPolyline( gmaps.GMap googleMap, Polyline polyline) { - List paths = []; - polyline.points.forEach((point) { - paths.add(_latLngToGmLatLng(point)); - }); + final List paths = []; + + polyline.points.map(_latLngToGmLatLng).forEach(paths.add); return gmaps.PolylineOptions() ..path = paths @@ -358,40 +379,40 @@ gmaps.PolylineOptions _polylineOptionsFromPolyline( // Translates a [CameraUpdate] into operations on a [gmaps.GMap]. void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { - final json = update.toJson() as List; + final List json = update.toJson() as List; switch (json[0]) { case 'newCameraPosition': - map.heading = json[1]['bearing']; - map.zoom = json[1]['zoom']; - map.panTo(gmaps.LatLng(json[1]['target'][0], json[1]['target'][1])); - map.tilt = json[1]['tilt']; + map.heading = json[1]['bearing'] as num?; + map.zoom = json[1]['zoom'] as num?; + map.panTo(gmaps.LatLng(json[1]['target'][0] as num?, json[1]['target'][1] as num?)); + map.tilt = json[1]['tilt'] as num?; break; case 'newLatLng': - map.panTo(gmaps.LatLng(json[1][0], json[1][1])); + map.panTo(gmaps.LatLng(json[1][0] as num?, json[1][1] as num?)); break; case 'newLatLngZoom': - map.zoom = json[2]; - map.panTo(gmaps.LatLng(json[1][0], json[1][1])); + map.zoom = json[2] as num?; + map.panTo(gmaps.LatLng(json[1][0] as num?, json[1][1] as num?)); break; case 'newLatLngBounds': map.fitBounds(gmaps.LatLngBounds( - gmaps.LatLng(json[1][0][0], json[1][0][1]), - gmaps.LatLng(json[1][1][0], json[1][1][1]))); + gmaps.LatLng(json[1][0][0] as num?, json[1][0][1] as num?), + gmaps.LatLng(json[1][1][0] as num?, json[1][1][1] as num?))); // padding = json[2]; // Needs package:google_maps ^4.0.0 to adjust the padding in fitBounds break; case 'scrollBy': - map.panBy(json[1], json[2]); + map.panBy(json[1] as num?, json[2] as num?); break; case 'zoomBy': gmaps.LatLng? focusLatLng; - double zoomDelta = json[1] ?? 0; + final double zoomDelta = json[1] as double? ?? 0; // Web only supports integer changes... - int newZoomDelta = zoomDelta < 0 ? zoomDelta.floor() : zoomDelta.ceil(); + final int newZoomDelta = zoomDelta < 0 ? zoomDelta.floor() : zoomDelta.ceil(); if (json.length == 3) { // With focus try { - focusLatLng = _pixelToLatLng(map, json[2][0], json[2][1]); + focusLatLng = _pixelToLatLng(map, json[2][0] as int, json[2][1] as int); } catch (e) { // https://github.com/a14n/dart-google-maps/issues/87 // print('Error computing new focus LatLng. JS Error: ' + e.toString()); @@ -409,7 +430,7 @@ void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { map.zoom = (map.zoom ?? 0) - 1; break; case 'zoomTo': - map.zoom = json[1]; + map.zoom = json[1] as num?; break; default: throw UnimplementedError('Unimplemented CameraMove: ${json[0]}.'); @@ -418,9 +439,9 @@ void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { // original JS by: Byron Singh (https://stackoverflow.com/a/30541162) gmaps.LatLng _pixelToLatLng(gmaps.GMap map, int x, int y) { - final bounds = map.bounds; - final projection = map.projection; - final zoom = map.zoom; + final gmaps.LatLngBounds? bounds = map.bounds; + final gmaps.Projection? projection = map.projection; + final num? zoom = map.zoom; assert( bounds != null, 'Map Bounds required to compute LatLng of screen x/y.'); @@ -429,15 +450,15 @@ gmaps.LatLng _pixelToLatLng(gmaps.GMap map, int x, int y) { assert(zoom != null, 'Current map zoom level required to compute LatLng of screen x/y'); - final ne = bounds!.northEast; - final sw = bounds.southWest; + final gmaps.LatLng ne = bounds!.northEast; + final gmaps.LatLng sw = bounds.southWest; - final topRight = projection!.fromLatLngToPoint!(ne)!; - final bottomLeft = projection.fromLatLngToPoint!(sw)!; + final gmaps.Point topRight = projection!.fromLatLngToPoint!(ne)!; + final gmaps.Point bottomLeft = projection.fromLatLngToPoint!(sw)!; - final scale = 1 << (zoom!.toInt()); // 2 ^ zoom + final int scale = 1 << (zoom!.toInt()); // 2 ^ zoom - final point = + final gmaps.Point point = gmaps.Point((x / scale) + bottomLeft.x!, (y / scale) + topRight.y!); return projection.fromPointToLatLng!(point)!; From 953ff94ddc2fe1b3dd5adfeaad0832b3f7c4ccc3 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 18 May 2022 16:14:32 -0700 Subject: [PATCH 08/18] Fix pubspec and CHANGELOG --- .../google_maps_flutter/google_maps_flutter_web/CHANGELOG.md | 4 ++++ .../google_maps_flutter/google_maps_flutter_web/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index f2fe971f4591..f33703d83a86 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.3 + +* Removes custom `analysis_options.yaml` (and fixes code to comply with newest rules). + ## 0.3.2+2 * Removes unnecessary imports. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 271d87d21092..fcfceb9f5509 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter repository: https://github.com/flutter/plugins/tree/main/packages/google_maps_flutter/google_maps_flutter_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 0.3.2+2 +version: 0.3.3 environment: sdk: ">=2.12.0 <3.0.0" @@ -21,8 +21,8 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - google_maps_flutter_platform_interface: ^2.1.2 google_maps: ^5.2.0 + google_maps_flutter_platform_interface: ^2.1.2 pedantic: ^1.10.0 sanitize_html: ^2.0.0 stream_transform: ^2.0.0 From a6b7646e643a897715e45cb3d88a8c77e367aef0 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 18 May 2022 17:16:58 -0700 Subject: [PATCH 09/18] Fix integration_test --- .../google_maps_controller_test.dart | 235 +++++++++--------- .../google_maps_plugin_test.dart | 190 +++++++------- .../example/integration_test/marker_test.dart | 38 +-- .../integration_test/markers_test.dart | 131 +++++----- .../integration_test/projection_test.dart | 26 +- .../resources/icon_image_base64.dart | 2 +- .../example/integration_test/shape_test.dart | 30 +-- .../example/integration_test/shapes_test.dart | 214 ++++++++-------- 8 files changed, 432 insertions(+), 434 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index 39aa641b10e4..a27e492986bd 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -18,9 +18,9 @@ import 'google_maps_controller_test.mocks.dart'; // This value is used when comparing long~num, like // LatLng values. -const _acceptableDelta = 0.0000000001; +const double _acceptableDelta = 0.0000000001; -@GenerateMocks([], customMocks: [ +@GenerateMocks([], customMocks: >[ MockSpec(returnNullOnMissingStub: true), MockSpec(returnNullOnMissingStub: true), MockSpec(returnNullOnMissingStub: true), @@ -32,9 +32,9 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('GoogleMapController', () { - final int mapId = 33930; + const int mapId = 33930; late GoogleMapController controller; - late StreamController stream; + late StreamController> stream; // Creates a controller with the default mapId and stream controller, and any `options` needed. GoogleMapController _createController({ @@ -59,7 +59,7 @@ void main() { } setUp(() { - stream = StreamController.broadcast(); + stream = StreamController>.broadcast(); }); group('construct/dispose', () { @@ -70,13 +70,13 @@ void main() { testWidgets('constructor creates widget', (WidgetTester tester) async { expect(controller.widget, isNotNull); expect(controller.widget, isA()); - expect((controller.widget as HtmlElementView).viewType, + expect((controller.widget! as HtmlElementView).viewType, endsWith('$mapId')); }); testWidgets('widget is cached when reused', (WidgetTester tester) async { - final first = controller.widget; - final again = controller.widget; + final Widget? first = controller.widget; + final Widget? again = controller.widget; expect(identical(first, again), isTrue); }); @@ -104,7 +104,7 @@ void main() { expect(() async { await controller.getScreenCoordinate( - LatLng(43.3072465, -5.6918241), + const LatLng(43.3072465, -5.6918241), ); }, throwsAssertionError); }); @@ -115,7 +115,7 @@ void main() { expect(() async { await controller.getLatLng( - ScreenCoordinate(x: 640, y: 480), + const ScreenCoordinate(x: 640, y: 480), ); }, throwsAssertionError); }); @@ -143,7 +143,7 @@ void main() { controller.dispose(); expect(() { - controller.updateCircles(CircleUpdates.from({}, {})); + controller.updateCircles(CircleUpdates.from({}, {})); }, throwsAssertionError); }); @@ -152,7 +152,7 @@ void main() { controller.dispose(); expect(() { - controller.updatePolygons(PolygonUpdates.from({}, {})); + controller.updatePolygons(PolygonUpdates.from({}, {})); }, throwsAssertionError); }); @@ -161,7 +161,7 @@ void main() { controller.dispose(); expect(() { - controller.updatePolylines(PolylineUpdates.from({}, {})); + controller.updatePolylines(PolylineUpdates.from({}, {})); }, throwsAssertionError); }); @@ -170,15 +170,15 @@ void main() { controller.dispose(); expect(() { - controller.updateMarkers(MarkerUpdates.from({}, {})); + controller.updateMarkers(MarkerUpdates.from({}, {})); }, throwsAssertionError); expect(() { - controller.showInfoWindow(MarkerId('any')); + controller.showInfoWindow(const MarkerId('any')); }, throwsAssertionError); expect(() { - controller.hideInfoWindow(MarkerId('any')); + controller.hideInfoWindow(const MarkerId('any')); }, throwsAssertionError); }); @@ -186,7 +186,7 @@ void main() { (WidgetTester tester) async { controller.dispose(); - expect(controller.isInfoWindowShown(MarkerId('any')), false); + expect(controller.isInfoWindowShown(const MarkerId('any')), false); }); }); }); @@ -219,16 +219,16 @@ void main() { controller.init(); // Trigger events on the map, and verify they've been broadcast to the stream - final capturedEvents = stream.stream.take(5); + final Stream> capturedEvents = stream.stream.take(5); gmaps.Event.trigger( - map, 'click', [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); + map, 'click', [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); gmaps.Event.trigger(map, 'rightclick', - [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); - gmaps.Event.trigger(map, 'bounds_changed', []); // Causes 2 events - gmaps.Event.trigger(map, 'idle', []); + [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); + gmaps.Event.trigger(map, 'bounds_changed', []); // Causes 2 events + gmaps.Event.trigger(map, 'idle', []); - final events = await capturedEvents.toList(); + final List> events = await capturedEvents.toList(); expect(events[0], isA()); expect(events[1], isA()); @@ -237,7 +237,7 @@ void main() { expect(events[4], isA()); }); - testWidgets('binds geometry controllers to map\'s', + testWidgets("binds geometry controllers to map's", (WidgetTester tester) async { controller = _createController(); controller.debugSetOverrides( @@ -257,44 +257,44 @@ void main() { }); testWidgets('renders initial geometry', (WidgetTester tester) async { - controller = _createController(circles: { - Circle( + controller = _createController(circles: { + const Circle( circleId: CircleId('circle-1'), zIndex: 1234, ), - }, markers: { - Marker( + }, markers: { + const Marker( markerId: MarkerId('marker-1'), infoWindow: InfoWindow( title: 'title for test', snippet: 'snippet for test', ), ), - }, polygons: { - Polygon(polygonId: PolygonId('polygon-1'), points: [ + }, polygons: { + const Polygon(polygonId: PolygonId('polygon-1'), points: [ LatLng(43.355114, -5.851333), LatLng(43.354797, -5.851860), LatLng(43.354469, -5.851318), LatLng(43.354762, -5.850824), ]), - Polygon( + const Polygon( polygonId: PolygonId('polygon-2-with-holes'), - points: [ + points: [ LatLng(43.355114, -5.851333), LatLng(43.354797, -5.851860), LatLng(43.354469, -5.851318), LatLng(43.354762, -5.850824), ], - holes: [ - [ + holes: >[ + [ LatLng(41.354797, -6.851860), LatLng(41.354469, -6.851318), LatLng(41.354762, -6.850824), ] ], ), - }, polylines: { - Polyline(polylineId: PolylineId('polyline-1'), points: [ + }, polylines: { + const Polyline(polylineId: PolylineId('polyline-1'), points: [ LatLng(43.355114, -5.851333), LatLng(43.354797, -5.851860), LatLng(43.354469, -5.851318), @@ -311,13 +311,13 @@ void main() { controller.init(); - final capturedCircles = + final Set capturedCircles = verify(circles.addCircles(captureAny)).captured[0] as Set; - final capturedMarkers = + final Set capturedMarkers = verify(markers.addMarkers(captureAny)).captured[0] as Set; - final capturedPolygons = verify(polygons.addPolygons(captureAny)) + final Set capturedPolygons = verify(polygons.addPolygons(captureAny)) .captured[0] as Set; - final capturedPolylines = verify(polylines.addPolylines(captureAny)) + final Set capturedPolylines = verify(polylines.addPolylines(captureAny)) .captured[0] as Set; expect(capturedCircles.first.circleId.value, 'circle-1'); @@ -334,8 +334,8 @@ void main() { testWidgets('empty infoWindow does not create InfoWindow instance.', (WidgetTester tester) async { - controller = _createController(markers: { - Marker(markerId: MarkerId('marker-1')), + controller = _createController(markers: { + const Marker(markerId: MarkerId('marker-1')), }); controller.debugSetOverrides( @@ -344,7 +344,7 @@ void main() { controller.init(); - final capturedMarkers = + final Set capturedMarkers = verify(markers.addMarkers(captureAny)).captured[0] as Set; expect(capturedMarkers.first.infoWindow, InfoWindow.noText); @@ -356,11 +356,11 @@ void main() { capturedOptions = null; }); testWidgets('translates initial options', (WidgetTester tester) async { - controller = _createController(options: { + controller = _createController(options: { 'mapType': 2, 'zoomControlsEnabled': true, }); - controller.debugSetOverrides(createMap: (_, options) { + controller.debugSetOverrides(createMap: (_, gmaps.MapOptions options) { capturedOptions = options; return map; }); @@ -377,10 +377,10 @@ void main() { testWidgets('disables gestureHandling with scrollGesturesEnabled false', (WidgetTester tester) async { - controller = _createController(options: { + controller = _createController(options: { 'scrollGesturesEnabled': false, }); - controller.debugSetOverrides(createMap: (_, options) { + controller.debugSetOverrides(createMap: (_, gmaps.MapOptions options) { capturedOptions = options; return map; }); @@ -395,10 +395,10 @@ void main() { testWidgets('disables gestureHandling with zoomGesturesEnabled false', (WidgetTester tester) async { - controller = _createController(options: { + controller = _createController(options: { 'zoomGesturesEnabled': false, }); - controller.debugSetOverrides(createMap: (_, options) { + controller.debugSetOverrides(createMap: (_, gmaps.MapOptions options) { capturedOptions = options; return map; }); @@ -414,7 +414,7 @@ void main() { testWidgets('sets initial position when passed', (WidgetTester tester) async { controller = _createController( - initialCameraPosition: CameraPosition( + initialCameraPosition: const CameraPosition( target: LatLng(43.308, -5.6910), zoom: 12, bearing: 0, @@ -422,7 +422,7 @@ void main() { ), ); - controller.debugSetOverrides(createMap: (_, options) { + controller.debugSetOverrides(createMap: (_, gmaps.MapOptions options) { capturedOptions = options; return map; }); @@ -444,7 +444,7 @@ void main() { testWidgets('initializes with traffic layer', (WidgetTester tester) async { - controller = _createController(options: { + controller = _createController(options: { 'trafficEnabled': true, }); controller.debugSetOverrides(createMap: (_, __) => map); @@ -472,7 +472,7 @@ void main() { group('updateRawOptions', () { testWidgets('can update `options`', (WidgetTester tester) async { - controller.updateRawOptions({ + controller.updateRawOptions({ 'mapType': 2, }); @@ -482,13 +482,13 @@ void main() { testWidgets('can turn on/off traffic', (WidgetTester tester) async { expect(controller.trafficLayer, isNull); - controller.updateRawOptions({ + controller.updateRawOptions({ 'trafficEnabled': true, }); expect(controller.trafficLayer, isNotNull); - controller.updateRawOptions({ + controller.updateRawOptions({ 'trafficEnabled': false, }); @@ -498,11 +498,11 @@ void main() { group('viewport getters', () { testWidgets('getVisibleRegion', (WidgetTester tester) async { - final gmCenter = map.center!; - final center = + final gmaps.LatLng gmCenter = map.center!; + final LatLng center = LatLng(gmCenter.lat.toDouble(), gmCenter.lng.toDouble()); - final bounds = await controller.getVisibleRegion(); + final LatLngBounds bounds = await controller.getVisibleRegion(); expect(bounds.contains(center), isTrue, reason: @@ -516,10 +516,10 @@ void main() { group('moveCamera', () { testWidgets('newLatLngZoom', (WidgetTester tester) async { - await (controller - .moveCamera(CameraUpdate.newLatLngZoom(LatLng(19, 26), 12))); + await controller + .moveCamera(CameraUpdate.newLatLngZoom(const LatLng(19, 26), 12,),); - final gmCenter = map.center!; + final gmaps.LatLng gmCenter = map.center!; expect(map.zoom, 12); expect(gmCenter.lat, closeTo(19, _acceptableDelta)); @@ -528,10 +528,7 @@ void main() { }); group('map.projection methods', () { - // These are too much for dart mockito, can't mock: - // map.projection.method() (in Javascript ;) ) - - // Caused https://github.com/flutter/flutter/issues/67606 + // Tested in projection_test.dart }); }); @@ -542,116 +539,116 @@ void main() { }); testWidgets('updateCircles', (WidgetTester tester) async { - final mock = MockCirclesController(); + final MockCirclesController mock = MockCirclesController(); controller.debugSetOverrides(circles: mock); - final previous = { - Circle(circleId: CircleId('to-be-updated')), - Circle(circleId: CircleId('to-be-removed')), + final Set previous = { + const Circle(circleId: CircleId('to-be-updated')), + const Circle(circleId: CircleId('to-be-removed')), }; - final current = { - Circle(circleId: CircleId('to-be-updated'), visible: false), - Circle(circleId: CircleId('to-be-added')), + final Set current = { + const Circle(circleId: CircleId('to-be-updated'), visible: false), + const Circle(circleId: CircleId('to-be-added')), }; controller.updateCircles(CircleUpdates.from(previous, current)); - verify(mock.removeCircles({ - CircleId('to-be-removed'), + verify(mock.removeCircles({ + const CircleId('to-be-removed'), })); - verify(mock.addCircles({ - Circle(circleId: CircleId('to-be-added')), + verify(mock.addCircles({ + const Circle(circleId: CircleId('to-be-added')), })); - verify(mock.changeCircles({ - Circle(circleId: CircleId('to-be-updated'), visible: false), + verify(mock.changeCircles({ + const Circle(circleId: CircleId('to-be-updated'), visible: false), })); }); testWidgets('updateMarkers', (WidgetTester tester) async { - final mock = MockMarkersController(); + final MockMarkersController mock = MockMarkersController(); controller.debugSetOverrides(markers: mock); - final previous = { - Marker(markerId: MarkerId('to-be-updated')), - Marker(markerId: MarkerId('to-be-removed')), + final Set previous = { + const Marker(markerId: MarkerId('to-be-updated')), + const Marker(markerId: MarkerId('to-be-removed')), }; - final current = { - Marker(markerId: MarkerId('to-be-updated'), visible: false), - Marker(markerId: MarkerId('to-be-added')), + final Set current = { + const Marker(markerId: MarkerId('to-be-updated'), visible: false), + const Marker(markerId: MarkerId('to-be-added')), }; controller.updateMarkers(MarkerUpdates.from(previous, current)); - verify(mock.removeMarkers({ - MarkerId('to-be-removed'), + verify(mock.removeMarkers({ + const MarkerId('to-be-removed'), })); - verify(mock.addMarkers({ - Marker(markerId: MarkerId('to-be-added')), + verify(mock.addMarkers({ + const Marker(markerId: MarkerId('to-be-added')), })); - verify(mock.changeMarkers({ - Marker(markerId: MarkerId('to-be-updated'), visible: false), + verify(mock.changeMarkers({ + const Marker(markerId: MarkerId('to-be-updated'), visible: false), })); }); testWidgets('updatePolygons', (WidgetTester tester) async { - final mock = MockPolygonsController(); + final MockPolygonsController mock = MockPolygonsController(); controller.debugSetOverrides(polygons: mock); - final previous = { - Polygon(polygonId: PolygonId('to-be-updated')), - Polygon(polygonId: PolygonId('to-be-removed')), + final Set previous = { + const Polygon(polygonId: PolygonId('to-be-updated')), + const Polygon(polygonId: PolygonId('to-be-removed')), }; - final current = { - Polygon(polygonId: PolygonId('to-be-updated'), visible: false), - Polygon(polygonId: PolygonId('to-be-added')), + final Set current = { + const Polygon(polygonId: PolygonId('to-be-updated'), visible: false), + const Polygon(polygonId: PolygonId('to-be-added')), }; controller.updatePolygons(PolygonUpdates.from(previous, current)); - verify(mock.removePolygons({ - PolygonId('to-be-removed'), + verify(mock.removePolygons({ + const PolygonId('to-be-removed'), })); - verify(mock.addPolygons({ - Polygon(polygonId: PolygonId('to-be-added')), + verify(mock.addPolygons({ + const Polygon(polygonId: PolygonId('to-be-added')), })); - verify(mock.changePolygons({ - Polygon(polygonId: PolygonId('to-be-updated'), visible: false), + verify(mock.changePolygons({ + const Polygon(polygonId: PolygonId('to-be-updated'), visible: false), })); }); testWidgets('updatePolylines', (WidgetTester tester) async { - final mock = MockPolylinesController(); + final MockPolylinesController mock = MockPolylinesController(); controller.debugSetOverrides(polylines: mock); - final previous = { - Polyline(polylineId: PolylineId('to-be-updated')), - Polyline(polylineId: PolylineId('to-be-removed')), + final Set previous = { + const Polyline(polylineId: PolylineId('to-be-updated')), + const Polyline(polylineId: PolylineId('to-be-removed')), }; - final current = { - Polyline(polylineId: PolylineId('to-be-updated'), visible: false), - Polyline(polylineId: PolylineId('to-be-added')), + final Set current = { + const Polyline(polylineId: PolylineId('to-be-updated'), visible: false), + const Polyline(polylineId: PolylineId('to-be-added')), }; controller.updatePolylines(PolylineUpdates.from(previous, current)); - verify(mock.removePolylines({ - PolylineId('to-be-removed'), + verify(mock.removePolylines({ + const PolylineId('to-be-removed'), })); - verify(mock.addPolylines({ - Polyline(polylineId: PolylineId('to-be-added')), + verify(mock.addPolylines({ + const Polyline(polylineId: PolylineId('to-be-added')), })); - verify(mock.changePolylines({ - Polyline(polylineId: PolylineId('to-be-updated'), visible: false), + verify(mock.changePolylines({ + const Polyline(polylineId: PolylineId('to-be-updated'), visible: false), })); }); testWidgets('infoWindow visibility', (WidgetTester tester) async { - final mock = MockMarkersController(); - final markerId = MarkerId('marker-with-infowindow'); + final MockMarkersController mock = MockMarkersController(); + const MarkerId markerId = MarkerId('marker-with-infowindow'); when(mock.isInfoWindowShown(markerId)).thenReturn(true); controller.debugSetOverrides(markers: mock); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart index a3cf86e593fe..61382989812a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart @@ -5,19 +5,18 @@ import 'dart:async'; import 'dart:js_util' show getProperty; -import 'package:integration_test/integration_test.dart'; import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; -import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; -import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; - import 'google_maps_plugin_test.mocks.dart'; -@GenerateMocks([], customMocks: [ +@GenerateMocks([], customMocks: >[ MockSpec(returnNullOnMissingStub: true), ]) @@ -51,7 +50,7 @@ void main() { group('after buildWidget', () { setUp(() { - plugin.debugSetMapById({0: controller}); + plugin.debugSetMapById({0: controller}); }); testWidgets('cannot call methods after dispose', @@ -69,13 +68,13 @@ void main() { }); group('buildView', () { - final testMapId = 33930; - final initialCameraPosition = CameraPosition(target: LatLng(0, 0)); + const int testMapId = 33930; + const CameraPosition initialCameraPosition = CameraPosition(target: LatLng(0, 0)); testWidgets( 'returns an HtmlElementView and caches the controller for later', (WidgetTester tester) async { - final Map cache = {}; + final Map cache = {}; plugin.debugSetMapById(cache); final Widget widget = plugin.buildView( @@ -106,11 +105,11 @@ void main() { testWidgets('returns cached instance if it already exists', (WidgetTester tester) async { - final expected = HtmlElementView(viewType: 'only-for-testing'); + const HtmlElementView expected = HtmlElementView(viewType: 'only-for-testing'); when(controller.widget).thenReturn(expected); - plugin.debugSetMapById({testMapId: controller}); + plugin.debugSetMapById({testMapId: controller}); - final widget = plugin.buildView( + final Widget widget = plugin.buildView( testMapId, onPlatformViewCreated, initialCameraPosition: initialCameraPosition, @@ -122,7 +121,7 @@ void main() { testWidgets( 'asynchronously reports onPlatformViewCreated the first time it happens', (WidgetTester tester) async { - final Map cache = {}; + final Map cache = {}; plugin.debugSetMapById(cache); plugin.buildView( @@ -157,47 +156,48 @@ void main() { }); group('setMapStyles', () { - String mapStyle = '''[{ - "featureType": "poi.park", - "elementType": "labels.text.fill", - "stylers": [{"color": "#6b9a76"}] - }]'''; + const String mapStyle = ''' +[{ + "featureType": "poi.park", + "elementType": "labels.text.fill", + "stylers": [{"color": "#6b9a76"}] +}]'''; testWidgets('translates styles for controller', (WidgetTester tester) async { - plugin.debugSetMapById({0: controller}); + plugin.debugSetMapById({0: controller}); await plugin.setMapStyle(mapStyle, mapId: 0); - var captured = + final dynamic captured = verify(controller.updateRawOptions(captureThat(isMap))).captured[0]; expect(captured, contains('styles')); - var styles = captured['styles']; + final List styles = captured['styles'] as List; expect(styles.length, 1); // Let's peek inside the styles... - var style = styles[0] as gmaps.MapTypeStyle; + final gmaps.MapTypeStyle style = styles[0]; expect(style.featureType, 'poi.park'); expect(style.elementType, 'labels.text.fill'); expect(style.stylers?.length, 1); - expect(getProperty(style.stylers![0]!, 'color'), '#6b9a76'); + expect(getProperty(style.stylers![0]!, 'color'), '#6b9a76'); }); }); group('Noop methods:', () { - int mapId = 0; + const int mapId = 0; setUp(() { - plugin.debugSetMapById({mapId: controller}); + plugin.debugSetMapById({mapId: controller}); }); // Options testWidgets('updateTileOverlays', (WidgetTester tester) async { - final update = - plugin.updateTileOverlays(mapId: mapId, newTileOverlays: {}); + final Future update = + plugin.updateTileOverlays(mapId: mapId, newTileOverlays: {}); expect(update, completion(null)); }); testWidgets('updateTileOverlays', (WidgetTester tester) async { - final update = - plugin.clearTileCache(TileOverlayId('any'), mapId: mapId); + final Future update = + plugin.clearTileCache(const TileOverlayId('any'), mapId: mapId); expect(update, completion(null)); }); }); @@ -205,13 +205,13 @@ void main() { // These methods only pass-through values from the plugin to the controller // so we verify them all together here... group('Pass-through methods:', () { - int mapId = 0; + const int mapId = 0; setUp(() { - plugin.debugSetMapById({mapId: controller}); + plugin.debugSetMapById({mapId: controller}); }); // Options testWidgets('updateMapOptions', (WidgetTester tester) async { - final expectedMapOptions = {'someOption': 12345}; + final Map expectedMapOptions = {'someOption': 12345}; await plugin.updateMapOptions(expectedMapOptions, mapId: mapId); @@ -219,28 +219,28 @@ void main() { }); // Geometry testWidgets('updateMarkers', (WidgetTester tester) async { - final expectedUpdates = MarkerUpdates.from({}, {}); + final MarkerUpdates expectedUpdates = MarkerUpdates.from({}, {}); await plugin.updateMarkers(expectedUpdates, mapId: mapId); verify(controller.updateMarkers(expectedUpdates)); }); testWidgets('updatePolygons', (WidgetTester tester) async { - final expectedUpdates = PolygonUpdates.from({}, {}); + final PolygonUpdates expectedUpdates = PolygonUpdates.from({}, {}); await plugin.updatePolygons(expectedUpdates, mapId: mapId); verify(controller.updatePolygons(expectedUpdates)); }); testWidgets('updatePolylines', (WidgetTester tester) async { - final expectedUpdates = PolylineUpdates.from({}, {}); + final PolylineUpdates expectedUpdates = PolylineUpdates.from({}, {}); await plugin.updatePolylines(expectedUpdates, mapId: mapId); verify(controller.updatePolylines(expectedUpdates)); }); testWidgets('updateCircles', (WidgetTester tester) async { - final expectedUpdates = CircleUpdates.from({}, {}); + final CircleUpdates expectedUpdates = CircleUpdates.from({}, {}); await plugin.updateCircles(expectedUpdates, mapId: mapId); @@ -248,16 +248,16 @@ void main() { }); // Camera testWidgets('animateCamera', (WidgetTester tester) async { - final expectedUpdates = - CameraUpdate.newLatLng(LatLng(43.3626, -5.8433)); + final CameraUpdate expectedUpdates = + CameraUpdate.newLatLng(const LatLng(43.3626, -5.8433)); await plugin.animateCamera(expectedUpdates, mapId: mapId); verify(controller.moveCamera(expectedUpdates)); }); testWidgets('moveCamera', (WidgetTester tester) async { - final expectedUpdates = - CameraUpdate.newLatLng(LatLng(43.3628, -5.8478)); + final CameraUpdate expectedUpdates = + CameraUpdate.newLatLng(const LatLng(43.3628, -5.8478)); await plugin.moveCamera(expectedUpdates, mapId: mapId); @@ -268,8 +268,8 @@ void main() { testWidgets('getVisibleRegion', (WidgetTester tester) async { when(controller.getVisibleRegion()) .thenAnswer((_) async => LatLngBounds( - northeast: LatLng(47.2359634, -68.0192019), - southwest: LatLng(34.5019594, -120.4974629), + northeast: const LatLng(47.2359634, -68.0192019), + southwest: const LatLng(34.5019594, -120.4974629), )); await plugin.getVisibleRegion(mapId: mapId); @@ -285,10 +285,10 @@ void main() { testWidgets('getScreenCoordinate', (WidgetTester tester) async { when(controller.getScreenCoordinate(any)).thenAnswer( - (_) async => ScreenCoordinate(x: 320, y: 240) // fake return + (_) async => const ScreenCoordinate(x: 320, y: 240) // fake return ); - final latLng = LatLng(43.3613, -5.8499); + const LatLng latLng = LatLng(43.3613, -5.8499); await plugin.getScreenCoordinate(latLng, mapId: mapId); @@ -297,10 +297,10 @@ void main() { testWidgets('getLatLng', (WidgetTester tester) async { when(controller.getLatLng(any)) - .thenAnswer((_) async => LatLng(43.3613, -5.8499) // fake return + .thenAnswer((_) async => const LatLng(43.3613, -5.8499) // fake return ); - final coordinates = ScreenCoordinate(x: 19, y: 26); + const ScreenCoordinate coordinates = ScreenCoordinate(x: 19, y: 26); await plugin.getLatLng(coordinates, mapId: mapId); @@ -309,7 +309,7 @@ void main() { // InfoWindows testWidgets('showMarkerInfoWindow', (WidgetTester tester) async { - final markerId = MarkerId('testing-123'); + const MarkerId markerId = MarkerId('testing-123'); await plugin.showMarkerInfoWindow(markerId, mapId: mapId); @@ -317,7 +317,7 @@ void main() { }); testWidgets('hideMarkerInfoWindow', (WidgetTester tester) async { - final markerId = MarkerId('testing-123'); + const MarkerId markerId = MarkerId('testing-123'); await plugin.hideMarkerInfoWindow(markerId, mapId: mapId); @@ -327,7 +327,7 @@ void main() { testWidgets('isMarkerInfoWindowShown', (WidgetTester tester) async { when(controller.isInfoWindowShown(any)).thenReturn(true); - final markerId = MarkerId('testing-123'); + const MarkerId markerId = MarkerId('testing-123'); await plugin.isMarkerInfoWindowShown(markerId, mapId: mapId); @@ -337,18 +337,18 @@ void main() { // Verify all event streams are filtered correctly from the main one... group('Event Streams', () { - int mapId = 0; - late StreamController streamController; + const int mapId = 0; + late StreamController> streamController; setUp(() { - streamController = StreamController.broadcast(); + streamController = StreamController>.broadcast(); when(controller.events) - .thenAnswer((realInvocation) => streamController.stream); - plugin.debugSetMapById({mapId: controller}); + .thenAnswer((Invocation realInvocation) => streamController.stream); + plugin.debugSetMapById({mapId: controller}); }); // Dispatches a few events in the global streamController, and expects *only* the passed event to be there. Future _testStreamFiltering( - Stream stream, MapEvent event) async { + Stream> stream, MapEvent event) async { Timer.run(() { streamController.add(_OtherMapEvent(mapId)); streamController.add(event); @@ -356,7 +356,7 @@ void main() { streamController.close(); }); - final events = await stream.toList(); + final List> events = await stream.toList(); expect(events.length, 1); expect(events[0], event); @@ -364,120 +364,120 @@ void main() { // Camera events testWidgets('onCameraMoveStarted', (WidgetTester tester) async { - final event = CameraMoveStartedEvent(mapId); + final CameraMoveStartedEvent event = CameraMoveStartedEvent(mapId); - final stream = plugin.onCameraMoveStarted(mapId: mapId); + final Stream stream = plugin.onCameraMoveStarted(mapId: mapId); - await _testStreamFiltering(stream, event); + await _testStreamFiltering(stream as Stream>, event as MapEvent); }); testWidgets('onCameraMoveStarted', (WidgetTester tester) async { - final event = CameraMoveEvent( + final CameraMoveEvent event = CameraMoveEvent( mapId, - CameraPosition( + const CameraPosition( target: LatLng(43.3790, -5.8660), ), ); - final stream = plugin.onCameraMove(mapId: mapId); + final Stream stream = plugin.onCameraMove(mapId: mapId); await _testStreamFiltering(stream, event); }); testWidgets('onCameraIdle', (WidgetTester tester) async { - final event = CameraIdleEvent(mapId); + final CameraIdleEvent event = CameraIdleEvent(mapId); - final stream = plugin.onCameraIdle(mapId: mapId); + final Stream stream = plugin.onCameraIdle(mapId: mapId); - await _testStreamFiltering(stream, event); + await _testStreamFiltering(stream as Stream>, event as MapEvent); }); // Marker events testWidgets('onMarkerTap', (WidgetTester tester) async { - final event = MarkerTapEvent(mapId, MarkerId('test-123')); + final MarkerTapEvent event = MarkerTapEvent(mapId, const MarkerId('test-123')); - final stream = plugin.onMarkerTap(mapId: mapId); + final Stream stream = plugin.onMarkerTap(mapId: mapId); await _testStreamFiltering(stream, event); }); testWidgets('onInfoWindowTap', (WidgetTester tester) async { - final event = InfoWindowTapEvent(mapId, MarkerId('test-123')); + final InfoWindowTapEvent event = InfoWindowTapEvent(mapId, const MarkerId('test-123')); - final stream = plugin.onInfoWindowTap(mapId: mapId); + final Stream stream = plugin.onInfoWindowTap(mapId: mapId); await _testStreamFiltering(stream, event); }); testWidgets('onMarkerDragStart', (WidgetTester tester) async { - final event = MarkerDragStartEvent( + final MarkerDragStartEvent event = MarkerDragStartEvent( mapId, - LatLng(43.3677, -5.8372), - MarkerId('test-123'), + const LatLng(43.3677, -5.8372), + const MarkerId('test-123'), ); - final stream = plugin.onMarkerDragStart(mapId: mapId); + final Stream stream = plugin.onMarkerDragStart(mapId: mapId); await _testStreamFiltering(stream, event); }); testWidgets('onMarkerDrag', (WidgetTester tester) async { - final event = MarkerDragEvent( + final MarkerDragEvent event = MarkerDragEvent( mapId, - LatLng(43.3677, -5.8372), - MarkerId('test-123'), + const LatLng(43.3677, -5.8372), + const MarkerId('test-123'), ); - final stream = plugin.onMarkerDrag(mapId: mapId); + final Stream stream = plugin.onMarkerDrag(mapId: mapId); await _testStreamFiltering(stream, event); }); testWidgets('onMarkerDragEnd', (WidgetTester tester) async { - final event = MarkerDragEndEvent( + final MarkerDragEndEvent event = MarkerDragEndEvent( mapId, - LatLng(43.3677, -5.8372), - MarkerId('test-123'), + const LatLng(43.3677, -5.8372), + const MarkerId('test-123'), ); - final stream = plugin.onMarkerDragEnd(mapId: mapId); + final Stream stream = plugin.onMarkerDragEnd(mapId: mapId); await _testStreamFiltering(stream, event); }); // Geometry testWidgets('onPolygonTap', (WidgetTester tester) async { - final event = PolygonTapEvent(mapId, PolygonId('test-123')); + final PolygonTapEvent event = PolygonTapEvent(mapId, const PolygonId('test-123')); - final stream = plugin.onPolygonTap(mapId: mapId); + final Stream stream = plugin.onPolygonTap(mapId: mapId); await _testStreamFiltering(stream, event); }); testWidgets('onPolylineTap', (WidgetTester tester) async { - final event = PolylineTapEvent(mapId, PolylineId('test-123')); + final PolylineTapEvent event = PolylineTapEvent(mapId, const PolylineId('test-123')); - final stream = plugin.onPolylineTap(mapId: mapId); + final Stream stream = plugin.onPolylineTap(mapId: mapId); await _testStreamFiltering(stream, event); }); testWidgets('onCircleTap', (WidgetTester tester) async { - final event = CircleTapEvent(mapId, CircleId('test-123')); + final CircleTapEvent event = CircleTapEvent(mapId, const CircleId('test-123')); - final stream = plugin.onCircleTap(mapId: mapId); + final Stream stream = plugin.onCircleTap(mapId: mapId); await _testStreamFiltering(stream, event); }); // Map taps testWidgets('onTap', (WidgetTester tester) async { - final event = MapTapEvent(mapId, LatLng(43.3597, -5.8458)); + final MapTapEvent event = MapTapEvent(mapId, const LatLng(43.3597, -5.8458)); - final stream = plugin.onTap(mapId: mapId); + final Stream stream = plugin.onTap(mapId: mapId); - await _testStreamFiltering(stream, event); + await _testStreamFiltering(stream as Stream>, event as MapEvent); }); testWidgets('onLongPress', (WidgetTester tester) async { - final event = MapLongPressEvent(mapId, LatLng(43.3608, -5.8425)); + final MapLongPressEvent event = MapLongPressEvent(mapId, const LatLng(43.3608, -5.8425)); - final stream = plugin.onLongPress(mapId: mapId); + final Stream stream = plugin.onLongPress(mapId: mapId); - await _testStreamFiltering(stream, event); + await _testStreamFiltering(stream as Stream>, event as MapEvent); }); }); }); } -class _OtherMapEvent extends MapEvent { - _OtherMapEvent(int mapId) : super(mapId, null); +class _OtherMapEvent extends MapEvent { + _OtherMapEvent(int mapId) : super(mapId, mapId); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart index cfa36febbbfe..cb53c5db6907 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart @@ -5,10 +5,10 @@ import 'dart:async'; import 'dart:html' as html; -import 'package:integration_test/integration_test.dart'; +import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; -import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; /// Test Markers void main() { @@ -40,7 +40,7 @@ void main() { } setUp(() { - _methodCalledCompleter = Completer(); + _methodCalledCompleter = Completer(); methodCalled = _methodCalledCompleter.future; }); @@ -55,7 +55,7 @@ void main() { MarkerController(marker: marker, onTap: onTap); // Trigger a click event... - gmaps.Event.trigger(marker, 'click', [gmaps.MapMouseEvent()]); + gmaps.Event.trigger(marker, 'click', [gmaps.MapMouseEvent()]); // The event handling is now truly async. Wait for it... expect(await methodCalled, isTrue); @@ -66,7 +66,7 @@ void main() { // Trigger a drag end event... gmaps.Event.trigger(marker, 'dragstart', - [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); + [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); expect(await methodCalled, isTrue); }); @@ -76,7 +76,7 @@ void main() { // Trigger a drag end event... gmaps.Event.trigger( - marker, 'drag', [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); + marker, 'drag', [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); expect(await methodCalled, isTrue); }); @@ -86,14 +86,14 @@ void main() { // Trigger a drag end event... gmaps.Event.trigger(marker, 'dragend', - [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); + [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); expect(await methodCalled, isTrue); }); testWidgets('update', (WidgetTester tester) async { - final controller = MarkerController(marker: marker); - final options = gmaps.MarkerOptions()..draggable = true; + final MarkerController controller = MarkerController(marker: marker); + final gmaps.MarkerOptions options = gmaps.MarkerOptions()..draggable = true; expect(marker.draggable, isNull); @@ -104,7 +104,7 @@ void main() { testWidgets('infoWindow null, showInfoWindow.', (WidgetTester tester) async { - final controller = MarkerController(marker: marker); + final MarkerController controller = MarkerController(marker: marker); controller.showInfoWindow(); @@ -112,10 +112,10 @@ void main() { }); testWidgets('showInfoWindow', (WidgetTester tester) async { - final infoWindow = gmaps.InfoWindow(); - final map = gmaps.GMap(html.DivElement()); + final gmaps.InfoWindow infoWindow = gmaps.InfoWindow(); + final gmaps.GMap map = gmaps.GMap(html.DivElement()); marker.set('map', map); - final controller = + final MarkerController controller = MarkerController(marker: marker, infoWindow: infoWindow); controller.showInfoWindow(); @@ -125,10 +125,10 @@ void main() { }); testWidgets('hideInfoWindow', (WidgetTester tester) async { - final infoWindow = gmaps.InfoWindow(); - final map = gmaps.GMap(html.DivElement()); + final gmaps.InfoWindow infoWindow = gmaps.InfoWindow(); + final gmaps.GMap map = gmaps.GMap(html.DivElement()); marker.set('map', map); - final controller = + final MarkerController controller = MarkerController(marker: marker, infoWindow: infoWindow); controller.hideInfoWindow(); @@ -141,8 +141,8 @@ void main() { late MarkerController controller; setUp(() { - final infoWindow = gmaps.InfoWindow(); - final map = gmaps.GMap(html.DivElement()); + final gmaps.InfoWindow infoWindow = gmaps.InfoWindow(); + final gmaps.GMap map = gmaps.GMap(html.DivElement()); marker.set('map', map); controller = MarkerController(marker: marker, infoWindow: infoWindow); }); @@ -155,7 +155,7 @@ void main() { testWidgets('cannot call update after remove', (WidgetTester tester) async { - final options = gmaps.MarkerOptions()..draggable = true; + final gmaps.MarkerOptions options = gmaps.MarkerOptions()..draggable = true; controller.remove(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart index 6f2bf610f77d..2e396b0a74aa 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:html' as html; import 'dart:js_util' show getProperty; +import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; @@ -20,54 +21,54 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('MarkersController', () { - late StreamController events; + late StreamController> events; late MarkersController controller; late gmaps.GMap map; setUp(() { - events = StreamController(); + events = StreamController>(); controller = MarkersController(stream: events); map = gmaps.GMap(html.DivElement()); controller.bindToMap(123, map); }); testWidgets('addMarkers', (WidgetTester tester) async { - final markers = { - Marker(markerId: MarkerId('1')), - Marker(markerId: MarkerId('2')), + final Set markers = { + const Marker(markerId: MarkerId('1')), + const Marker(markerId: MarkerId('2')), }; controller.addMarkers(markers); expect(controller.markers.length, 2); - expect(controller.markers, contains(MarkerId('1'))); - expect(controller.markers, contains(MarkerId('2'))); - expect(controller.markers, isNot(contains(MarkerId('66')))); + expect(controller.markers, contains(const MarkerId('1'))); + expect(controller.markers, contains(const MarkerId('2'))); + expect(controller.markers, isNot(contains(const MarkerId('66')))); }); testWidgets('changeMarkers', (WidgetTester tester) async { - final markers = { - Marker(markerId: MarkerId('1')), + final Set markers = { + const Marker(markerId: MarkerId('1')), }; controller.addMarkers(markers); - expect(controller.markers[MarkerId('1')]?.marker?.draggable, isFalse); + expect(controller.markers[const MarkerId('1')]?.marker?.draggable, isFalse); // Update the marker with radius 10 - final updatedMarkers = { - Marker(markerId: MarkerId('1'), draggable: true), + final Set updatedMarkers = { + const Marker(markerId: MarkerId('1'), draggable: true), }; controller.changeMarkers(updatedMarkers); expect(controller.markers.length, 1); - expect(controller.markers[MarkerId('1')]?.marker?.draggable, isTrue); + expect(controller.markers[const MarkerId('1')]?.marker?.draggable, isTrue); }); testWidgets('removeMarkers', (WidgetTester tester) async { - final markers = { - Marker(markerId: MarkerId('1')), - Marker(markerId: MarkerId('2')), - Marker(markerId: MarkerId('3')), + final Set markers = { + const Marker(markerId: MarkerId('1')), + const Marker(markerId: MarkerId('2')), + const Marker(markerId: MarkerId('3')), }; controller.addMarkers(markers); @@ -75,91 +76,91 @@ void main() { expect(controller.markers.length, 3); // Remove some markers... - final markerIdsToRemove = { - MarkerId('1'), - MarkerId('3'), + final Set markerIdsToRemove = { + const MarkerId('1'), + const MarkerId('3'), }; controller.removeMarkers(markerIdsToRemove); expect(controller.markers.length, 1); - expect(controller.markers, isNot(contains(MarkerId('1')))); - expect(controller.markers, contains(MarkerId('2'))); - expect(controller.markers, isNot(contains(MarkerId('3')))); + expect(controller.markers, isNot(contains(const MarkerId('1')))); + expect(controller.markers, contains(const MarkerId('2'))); + expect(controller.markers, isNot(contains(const MarkerId('3')))); }); testWidgets('InfoWindow show/hide', (WidgetTester tester) async { - final markers = { - Marker( + final Set markers = { + const Marker( markerId: MarkerId('1'), - infoWindow: InfoWindow(title: "Title", snippet: "Snippet"), + infoWindow: InfoWindow(title: 'Title', snippet: 'Snippet'), ), }; controller.addMarkers(markers); - expect(controller.markers[MarkerId('1')]?.infoWindowShown, isFalse); + expect(controller.markers[const MarkerId('1')]?.infoWindowShown, isFalse); - controller.showMarkerInfoWindow(MarkerId('1')); + controller.showMarkerInfoWindow(const MarkerId('1')); - expect(controller.markers[MarkerId('1')]?.infoWindowShown, isTrue); + expect(controller.markers[const MarkerId('1')]?.infoWindowShown, isTrue); - controller.hideMarkerInfoWindow(MarkerId('1')); + controller.hideMarkerInfoWindow(const MarkerId('1')); - expect(controller.markers[MarkerId('1')]?.infoWindowShown, isFalse); + expect(controller.markers[const MarkerId('1')]?.infoWindowShown, isFalse); }); // https://github.com/flutter/flutter/issues/67380 testWidgets('only single InfoWindow is visible', (WidgetTester tester) async { - final markers = { - Marker( + final Set markers = { + const Marker( markerId: MarkerId('1'), - infoWindow: InfoWindow(title: "Title", snippet: "Snippet"), + infoWindow: InfoWindow(title: 'Title', snippet: 'Snippet'), ), - Marker( + const Marker( markerId: MarkerId('2'), - infoWindow: InfoWindow(title: "Title", snippet: "Snippet"), + infoWindow: InfoWindow(title: 'Title', snippet: 'Snippet'), ), }; controller.addMarkers(markers); - expect(controller.markers[MarkerId('1')]?.infoWindowShown, isFalse); - expect(controller.markers[MarkerId('2')]?.infoWindowShown, isFalse); + expect(controller.markers[const MarkerId('1')]?.infoWindowShown, isFalse); + expect(controller.markers[const MarkerId('2')]?.infoWindowShown, isFalse); - controller.showMarkerInfoWindow(MarkerId('1')); + controller.showMarkerInfoWindow(const MarkerId('1')); - expect(controller.markers[MarkerId('1')]?.infoWindowShown, isTrue); - expect(controller.markers[MarkerId('2')]?.infoWindowShown, isFalse); + expect(controller.markers[const MarkerId('1')]?.infoWindowShown, isTrue); + expect(controller.markers[const MarkerId('2')]?.infoWindowShown, isFalse); - controller.showMarkerInfoWindow(MarkerId('2')); + controller.showMarkerInfoWindow(const MarkerId('2')); - expect(controller.markers[MarkerId('1')]?.infoWindowShown, isFalse); - expect(controller.markers[MarkerId('2')]?.infoWindowShown, isTrue); + expect(controller.markers[const MarkerId('1')]?.infoWindowShown, isFalse); + expect(controller.markers[const MarkerId('2')]?.infoWindowShown, isTrue); }); // https://github.com/flutter/flutter/issues/66622 testWidgets('markers with custom bitmap icon work', (WidgetTester tester) async { - final bytes = Base64Decoder().convert(iconImageBase64); - final markers = { + final Uint8List bytes = const Base64Decoder().convert(iconImageBase64); + final Set markers = { Marker( - markerId: MarkerId('1'), icon: BitmapDescriptor.fromBytes(bytes)), + markerId: const MarkerId('1'), icon: BitmapDescriptor.fromBytes(bytes)), }; controller.addMarkers(markers); expect(controller.markers.length, 1); - expect(controller.markers[MarkerId('1')]?.marker?.icon, isNotNull); + expect(controller.markers[const MarkerId('1')]?.marker?.icon, isNotNull); - final blobUrl = getProperty( - controller.markers[MarkerId('1')]!.marker!.icon!, + final String blobUrl = getProperty( + controller.markers[const MarkerId('1')]!.marker!.icon!, 'url', ); expect(blobUrl, startsWith('blob:')); - final response = await http.get(Uri.parse(blobUrl)); + final http.Response response = await http.get(Uri.parse(blobUrl)); expect(response.bodyBytes, bytes, reason: @@ -169,8 +170,8 @@ void main() { // https://github.com/flutter/flutter/issues/67854 testWidgets('InfoWindow snippet can have links', (WidgetTester tester) async { - final markers = { - Marker( + final Set markers = { + const Marker( markerId: MarkerId('1'), infoWindow: InfoWindow( title: 'title for test', @@ -182,19 +183,19 @@ void main() { controller.addMarkers(markers); expect(controller.markers.length, 1); - final content = controller.markers[MarkerId('1')]?.infoWindow?.content - as html.HtmlElement; - expect(content.innerHtml, contains('title for test')); + final html.HtmlElement? content = controller.markers[const MarkerId('1')]?.infoWindow?.content + as html.HtmlElement?; + expect(content?.innerHtml, contains('title for test')); expect( - content.innerHtml, + content?.innerHtml, contains( 'Go to Google >>>')); }); // https://github.com/flutter/flutter/issues/67289 testWidgets('InfoWindow content is clickable', (WidgetTester tester) async { - final markers = { - Marker( + final Set markers = { + const Marker( markerId: MarkerId('1'), infoWindow: InfoWindow( title: 'title for test', @@ -206,15 +207,15 @@ void main() { controller.addMarkers(markers); expect(controller.markers.length, 1); - final content = controller.markers[MarkerId('1')]?.infoWindow?.content - as html.HtmlElement; + final html.HtmlElement? content = controller.markers[const MarkerId('1')]?.infoWindow?.content + as html.HtmlElement?; - content.click(); + content?.click(); - final event = await events.stream.first; + final MapEvent event = await events.stream.first; expect(event, isA()); - expect((event as InfoWindowTapEvent).value, equals(MarkerId('1'))); + expect((event as InfoWindowTapEvent).value, equals(const MarkerId('1'))); }); }); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/projection_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/projection_test.dart index 1bf0f10f50c8..14e4156b87ec 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/projection_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/projection_test.dart @@ -17,20 +17,20 @@ import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platf import 'package:integration_test/integration_test.dart'; // This value is used when comparing long~num, like LatLng values. -const _acceptableLatLngDelta = 0.0000000001; +const double _acceptableLatLngDelta = 0.0000000001; // This value is used when comparing pixel measurements, mostly to gloss over // browser rounding errors. -const _acceptablePixelDelta = 1; +const int _acceptablePixelDelta = 1; /// Test Google Map Controller void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('Methods that require a proper Projection', () { - final LatLng center = LatLng(43.3078, -5.6958); - final Size size = Size(320, 240); - final CameraPosition initialCamera = CameraPosition( + const LatLng center = LatLng(43.3078, -5.6958); + const Size size = Size(320, 240); + const CameraPosition initialCamera = CameraPosition( target: center, zoom: 14, ); @@ -48,7 +48,7 @@ void main() { group('getScreenCoordinate', () { testWidgets('target of map is in center of widget', (WidgetTester tester) async { - pumpCenteredMap( + await pumpCenteredMap( tester, initialCamera: initialCamera, size: size, @@ -72,7 +72,7 @@ void main() { testWidgets('NorthWest of visible region corresponds to x:0, y:0', (WidgetTester tester) async { - pumpCenteredMap( + await pumpCenteredMap( tester, initialCamera: initialCamera, size: size, @@ -96,7 +96,7 @@ void main() { testWidgets( 'SouthEast of visible region corresponds to x:size.width, y:size.height', (WidgetTester tester) async { - pumpCenteredMap( + await pumpCenteredMap( tester, initialCamera: initialCamera, size: size, @@ -121,7 +121,7 @@ void main() { group('getLatLng', () { testWidgets('Center of widget is the target of map', (WidgetTester tester) async { - pumpCenteredMap( + await pumpCenteredMap( tester, initialCamera: initialCamera, size: size, @@ -146,7 +146,7 @@ void main() { testWidgets('Top-left of widget is NorthWest bound of map', (WidgetTester tester) async { - pumpCenteredMap( + await pumpCenteredMap( tester, initialCamera: initialCamera, size: size, @@ -161,7 +161,7 @@ void main() { ); final LatLng coords = await controller.getLatLng( - ScreenCoordinate(x: 0, y: 0), + const ScreenCoordinate(x: 0, y: 0), ); expect( @@ -176,7 +176,7 @@ void main() { testWidgets('Bottom-right of widget is SouthWest bound of map', (WidgetTester tester) async { - pumpCenteredMap( + await pumpCenteredMap( tester, initialCamera: initialCamera, size: size, @@ -208,7 +208,7 @@ void main() { } // Pumps a CenteredMap Widget into a given tester, with some parameters -void pumpCenteredMap( +Future pumpCenteredMap( WidgetTester tester, { required CameraPosition initialCamera, Size size = const Size(320, 240), diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart index 6010f0107031..d08e96a65333 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/resources/icon_image_base64.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -final iconImageBase64 = +const String iconImageBase64 = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAIRlWElmTU' '0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIA' 'AIdpAAQAAAABAAAAWgAAAAAAAABIAAAAAQAAAEgAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQ' diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart index 547aaec6dc0a..fa9f55b9c3f0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart @@ -4,10 +4,10 @@ import 'dart:async'; -import 'package:integration_test/integration_test.dart'; +import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; -import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; /// Test Shapes (Circle, Polygon, Polyline) void main() { @@ -27,7 +27,7 @@ void main() { } setUp(() { - _methodCalledCompleter = Completer(); + _methodCalledCompleter = Completer(); methodCalled = _methodCalledCompleter.future; }); @@ -42,15 +42,15 @@ void main() { CircleController(circle: circle, consumeTapEvents: true, onTap: onTap); // Trigger a click event... - gmaps.Event.trigger(circle, 'click', [gmaps.MapMouseEvent()]); + gmaps.Event.trigger(circle, 'click', [gmaps.MapMouseEvent()]); // The event handling is now truly async. Wait for it... expect(await methodCalled, isTrue); }); testWidgets('update', (WidgetTester tester) async { - final controller = CircleController(circle: circle); - final options = gmaps.CircleOptions()..draggable = true; + final CircleController controller = CircleController(circle: circle); + final gmaps.CircleOptions options = gmaps.CircleOptions()..draggable = true; expect(circle.draggable, isNull); @@ -74,7 +74,7 @@ void main() { testWidgets('cannot call update after remove', (WidgetTester tester) async { - final options = gmaps.CircleOptions()..draggable = true; + final gmaps.CircleOptions options = gmaps.CircleOptions()..draggable = true; controller.remove(); @@ -96,15 +96,15 @@ void main() { PolygonController(polygon: polygon, consumeTapEvents: true, onTap: onTap); // Trigger a click event... - gmaps.Event.trigger(polygon, 'click', [gmaps.MapMouseEvent()]); + gmaps.Event.trigger(polygon, 'click', [gmaps.MapMouseEvent()]); // The event handling is now truly async. Wait for it... expect(await methodCalled, isTrue); }); testWidgets('update', (WidgetTester tester) async { - final controller = PolygonController(polygon: polygon); - final options = gmaps.PolygonOptions()..draggable = true; + final PolygonController controller = PolygonController(polygon: polygon); + final gmaps.PolygonOptions options = gmaps.PolygonOptions()..draggable = true; expect(polygon.draggable, isNull); @@ -128,7 +128,7 @@ void main() { testWidgets('cannot call update after remove', (WidgetTester tester) async { - final options = gmaps.PolygonOptions()..draggable = true; + final gmaps.PolygonOptions options = gmaps.PolygonOptions()..draggable = true; controller.remove(); @@ -151,15 +151,15 @@ void main() { polyline: polyline, consumeTapEvents: true, onTap: onTap); // Trigger a click event... - gmaps.Event.trigger(polyline, 'click', [gmaps.MapMouseEvent()]); + gmaps.Event.trigger(polyline, 'click', [gmaps.MapMouseEvent()]); // The event handling is now truly async. Wait for it... expect(await methodCalled, isTrue); }); testWidgets('update', (WidgetTester tester) async { - final controller = PolylineController(polyline: polyline); - final options = gmaps.PolylineOptions()..draggable = true; + final PolylineController controller = PolylineController(polyline: polyline); + final gmaps.PolylineOptions options = gmaps.PolylineOptions()..draggable = true; expect(polyline.draggable, isNull); @@ -183,7 +183,7 @@ void main() { testWidgets('cannot call update after remove', (WidgetTester tester) async { - final options = gmaps.PolylineOptions()..draggable = true; + final gmaps.PolylineOptions options = gmaps.PolylineOptions()..draggable = true; controller.remove(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart index 80b4e0823bb5..a0c3478bf4e7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart @@ -3,20 +3,20 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:ui'; import 'dart:html' as html; +import 'dart:ui'; -import 'package:integration_test/integration_test.dart'; -import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; -import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:flutter_test/flutter_test.dart'; import 'package:google_maps/google_maps.dart' as gmaps; import 'package:google_maps/google_maps_geometry.dart' as geometry; -import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; +import 'package:google_maps_flutter_web/google_maps_flutter_web.dart'; +import 'package:integration_test/integration_test.dart'; // This value is used when comparing the results of // converting from a byte value to a double between 0 and 1. // (For Color opacity values, for example) -const _acceptableDelta = 0.01; +const double _acceptableDelta = 0.01; /// Test Shapes (Circle, Polygon, Polyline) void main() { @@ -29,51 +29,51 @@ void main() { }); group('CirclesController', () { - late StreamController events; + late StreamController> events; late CirclesController controller; setUp(() { - events = StreamController(); + events = StreamController>(); controller = CirclesController(stream: events); controller.bindToMap(123, map); }); testWidgets('addCircles', (WidgetTester tester) async { - final circles = { - Circle(circleId: CircleId('1')), - Circle(circleId: CircleId('2')), + final Set circles = { + const Circle(circleId: CircleId('1')), + const Circle(circleId: CircleId('2')), }; controller.addCircles(circles); expect(controller.circles.length, 2); - expect(controller.circles, contains(CircleId('1'))); - expect(controller.circles, contains(CircleId('2'))); - expect(controller.circles, isNot(contains(CircleId('66')))); + expect(controller.circles, contains(const CircleId('1'))); + expect(controller.circles, contains(const CircleId('2'))); + expect(controller.circles, isNot(contains(const CircleId('66')))); }); testWidgets('changeCircles', (WidgetTester tester) async { - final circles = { - Circle(circleId: CircleId('1')), + final Set circles = { + const Circle(circleId: CircleId('1')), }; controller.addCircles(circles); - expect(controller.circles[CircleId('1')]?.circle?.visible, isTrue); + expect(controller.circles[const CircleId('1')]?.circle?.visible, isTrue); - final updatedCircles = { - Circle(circleId: CircleId('1'), visible: false), + final Set updatedCircles = { + const Circle(circleId: CircleId('1'), visible: false), }; controller.changeCircles(updatedCircles); expect(controller.circles.length, 1); - expect(controller.circles[CircleId('1')]?.circle?.visible, isFalse); + expect(controller.circles[const CircleId('1')]?.circle?.visible, isFalse); }); testWidgets('removeCircles', (WidgetTester tester) async { - final circles = { - Circle(circleId: CircleId('1')), - Circle(circleId: CircleId('2')), - Circle(circleId: CircleId('3')), + final Set circles = { + const Circle(circleId: CircleId('1')), + const Circle(circleId: CircleId('2')), + const Circle(circleId: CircleId('3')), }; controller.addCircles(circles); @@ -81,22 +81,22 @@ void main() { expect(controller.circles.length, 3); // Remove some circles... - final circleIdsToRemove = { - CircleId('1'), - CircleId('3'), + final Set circleIdsToRemove = { + const CircleId('1'), + const CircleId('3'), }; controller.removeCircles(circleIdsToRemove); expect(controller.circles.length, 1); - expect(controller.circles, isNot(contains(CircleId('1')))); - expect(controller.circles, contains(CircleId('2'))); - expect(controller.circles, isNot(contains(CircleId('3')))); + expect(controller.circles, isNot(contains(const CircleId('1')))); + expect(controller.circles, contains(const CircleId('2'))); + expect(controller.circles, isNot(contains(const CircleId('3')))); }); testWidgets('Converts colors to CSS', (WidgetTester tester) async { - final circles = { - Circle( + final Set circles = { + const Circle( circleId: CircleId('1'), fillColor: Color(0x7FFABADA), strokeColor: Color(0xFFC0FFEE), @@ -105,7 +105,7 @@ void main() { controller.addCircles(circles); - final circle = controller.circles.values.first.circle!; + final gmaps.Circle circle = controller.circles.values.first.circle!; expect(circle.get('fillColor'), '#fabada'); expect(circle.get('fillOpacity'), closeTo(0.5, _acceptableDelta)); @@ -115,52 +115,52 @@ void main() { }); group('PolygonsController', () { - late StreamController events; + late StreamController> events; late PolygonsController controller; setUp(() { - events = StreamController(); + events = StreamController>(); controller = PolygonsController(stream: events); controller.bindToMap(123, map); }); testWidgets('addPolygons', (WidgetTester tester) async { - final polygons = { - Polygon(polygonId: PolygonId('1')), - Polygon(polygonId: PolygonId('2')), + final Set polygons = { + const Polygon(polygonId: PolygonId('1')), + const Polygon(polygonId: PolygonId('2')), }; controller.addPolygons(polygons); expect(controller.polygons.length, 2); - expect(controller.polygons, contains(PolygonId('1'))); - expect(controller.polygons, contains(PolygonId('2'))); - expect(controller.polygons, isNot(contains(PolygonId('66')))); + expect(controller.polygons, contains(const PolygonId('1'))); + expect(controller.polygons, contains(const PolygonId('2'))); + expect(controller.polygons, isNot(contains(const PolygonId('66')))); }); testWidgets('changePolygons', (WidgetTester tester) async { - final polygons = { - Polygon(polygonId: PolygonId('1')), + final Set polygons = { + const Polygon(polygonId: PolygonId('1')), }; controller.addPolygons(polygons); - expect(controller.polygons[PolygonId('1')]?.polygon?.visible, isTrue); + expect(controller.polygons[const PolygonId('1')]?.polygon?.visible, isTrue); // Update the polygon - final updatedPolygons = { - Polygon(polygonId: PolygonId('1'), visible: false), + final Set updatedPolygons = { + const Polygon(polygonId: PolygonId('1'), visible: false), }; controller.changePolygons(updatedPolygons); expect(controller.polygons.length, 1); - expect(controller.polygons[PolygonId('1')]?.polygon?.visible, isFalse); + expect(controller.polygons[const PolygonId('1')]?.polygon?.visible, isFalse); }); testWidgets('removePolygons', (WidgetTester tester) async { - final polygons = { - Polygon(polygonId: PolygonId('1')), - Polygon(polygonId: PolygonId('2')), - Polygon(polygonId: PolygonId('3')), + final Set polygons = { + const Polygon(polygonId: PolygonId('1')), + const Polygon(polygonId: PolygonId('2')), + const Polygon(polygonId: PolygonId('3')), }; controller.addPolygons(polygons); @@ -168,22 +168,22 @@ void main() { expect(controller.polygons.length, 3); // Remove some polygons... - final polygonIdsToRemove = { - PolygonId('1'), - PolygonId('3'), + final Set polygonIdsToRemove = { + const PolygonId('1'), + const PolygonId('3'), }; controller.removePolygons(polygonIdsToRemove); expect(controller.polygons.length, 1); - expect(controller.polygons, isNot(contains(PolygonId('1')))); - expect(controller.polygons, contains(PolygonId('2'))); - expect(controller.polygons, isNot(contains(PolygonId('3')))); + expect(controller.polygons, isNot(contains(const PolygonId('1')))); + expect(controller.polygons, contains(const PolygonId('2'))); + expect(controller.polygons, isNot(contains(const PolygonId('3')))); }); testWidgets('Converts colors to CSS', (WidgetTester tester) async { - final polygons = { - Polygon( + final Set polygons = { + const Polygon( polygonId: PolygonId('1'), fillColor: Color(0x7FFABADA), strokeColor: Color(0xFFC0FFEE), @@ -192,7 +192,7 @@ void main() { controller.addPolygons(polygons); - final polygon = controller.polygons.values.first.polygon!; + final gmaps.Polygon polygon = controller.polygons.values.first.polygon!; expect(polygon.get('fillColor'), '#fabada'); expect(polygon.get('fillOpacity'), closeTo(0.5, _acceptableDelta)); @@ -201,16 +201,16 @@ void main() { }); testWidgets('Handle Polygons with holes', (WidgetTester tester) async { - final polygons = { - Polygon( + final Set polygons = { + const Polygon( polygonId: PolygonId('BermudaTriangle'), - points: [ + points: [ LatLng(25.774, -80.19), LatLng(18.466, -66.118), LatLng(32.321, -64.757), ], - holes: [ - [ + holes: >[ + [ LatLng(28.745, -70.579), LatLng(29.57, -67.514), LatLng(27.339, -66.668), @@ -222,21 +222,21 @@ void main() { controller.addPolygons(polygons); expect(controller.polygons.length, 1); - expect(controller.polygons, contains(PolygonId('BermudaTriangle'))); - expect(controller.polygons, isNot(contains(PolygonId('66')))); + expect(controller.polygons, contains(const PolygonId('BermudaTriangle'))); + expect(controller.polygons, isNot(contains(const PolygonId('66')))); }); testWidgets('Polygon with hole has a hole', (WidgetTester tester) async { - final polygons = { - Polygon( + final Set polygons = { + const Polygon( polygonId: PolygonId('BermudaTriangle'), - points: [ + points: [ LatLng(25.774, -80.19), LatLng(18.466, -66.118), LatLng(32.321, -64.757), ], - holes: [ - [ + holes: >[ + [ LatLng(28.745, -70.579), LatLng(29.57, -67.514), LatLng(27.339, -66.668), @@ -247,24 +247,24 @@ void main() { controller.addPolygons(polygons); - final polygon = controller.polygons.values.first.polygon; - final pointInHole = gmaps.LatLng(28.632, -68.401); + final gmaps.Polygon? polygon = controller.polygons.values.first.polygon; + final gmaps.LatLng pointInHole = gmaps.LatLng(28.632, -68.401); expect(geometry.Poly.containsLocation(pointInHole, polygon), false); }); testWidgets('Hole Path gets reversed to display correctly', (WidgetTester tester) async { - final polygons = { - Polygon( + final Set polygons = { + const Polygon( polygonId: PolygonId('BermudaTriangle'), - points: [ + points: [ LatLng(25.774, -80.19), LatLng(18.466, -66.118), LatLng(32.321, -64.757), ], - holes: [ - [ + holes: >[ + [ LatLng(27.339, -66.668), LatLng(29.57, -67.514), LatLng(28.745, -70.579), @@ -275,7 +275,7 @@ void main() { controller.addPolygons(polygons); - final paths = controller.polygons.values.first.polygon!.paths!; + final gmaps.MVCArray?> paths = controller.polygons.values.first.polygon!.paths!; expect(paths.getAt(1)?.getAt(0)?.lat, 28.745); expect(paths.getAt(1)?.getAt(1)?.lat, 29.57); @@ -284,51 +284,51 @@ void main() { }); group('PolylinesController', () { - late StreamController events; + late StreamController> events; late PolylinesController controller; setUp(() { - events = StreamController(); + events = StreamController>(); controller = PolylinesController(stream: events); controller.bindToMap(123, map); }); testWidgets('addPolylines', (WidgetTester tester) async { - final polylines = { - Polyline(polylineId: PolylineId('1')), - Polyline(polylineId: PolylineId('2')), + final Set polylines = { + const Polyline(polylineId: PolylineId('1')), + const Polyline(polylineId: PolylineId('2')), }; controller.addPolylines(polylines); expect(controller.lines.length, 2); - expect(controller.lines, contains(PolylineId('1'))); - expect(controller.lines, contains(PolylineId('2'))); - expect(controller.lines, isNot(contains(PolylineId('66')))); + expect(controller.lines, contains(const PolylineId('1'))); + expect(controller.lines, contains(const PolylineId('2'))); + expect(controller.lines, isNot(contains(const PolylineId('66')))); }); testWidgets('changePolylines', (WidgetTester tester) async { - final polylines = { - Polyline(polylineId: PolylineId('1')), + final Set polylines = { + const Polyline(polylineId: PolylineId('1')), }; controller.addPolylines(polylines); - expect(controller.lines[PolylineId('1')]?.line?.visible, isTrue); + expect(controller.lines[const PolylineId('1')]?.line?.visible, isTrue); - final updatedPolylines = { - Polyline(polylineId: PolylineId('1'), visible: false), + final Set updatedPolylines = { + const Polyline(polylineId: PolylineId('1'), visible: false), }; controller.changePolylines(updatedPolylines); expect(controller.lines.length, 1); - expect(controller.lines[PolylineId('1')]?.line?.visible, isFalse); + expect(controller.lines[const PolylineId('1')]?.line?.visible, isFalse); }); testWidgets('removePolylines', (WidgetTester tester) async { - final polylines = { - Polyline(polylineId: PolylineId('1')), - Polyline(polylineId: PolylineId('2')), - Polyline(polylineId: PolylineId('3')), + final Set polylines = { + const Polyline(polylineId: PolylineId('1')), + const Polyline(polylineId: PolylineId('2')), + const Polyline(polylineId: PolylineId('3')), }; controller.addPolylines(polylines); @@ -336,22 +336,22 @@ void main() { expect(controller.lines.length, 3); // Remove some polylines... - final polylineIdsToRemove = { - PolylineId('1'), - PolylineId('3'), + final Set polylineIdsToRemove = { + const PolylineId('1'), + const PolylineId('3'), }; controller.removePolylines(polylineIdsToRemove); expect(controller.lines.length, 1); - expect(controller.lines, isNot(contains(PolylineId('1')))); - expect(controller.lines, contains(PolylineId('2'))); - expect(controller.lines, isNot(contains(PolylineId('3')))); + expect(controller.lines, isNot(contains(const PolylineId('1')))); + expect(controller.lines, contains(const PolylineId('2'))); + expect(controller.lines, isNot(contains(const PolylineId('3')))); }); testWidgets('Converts colors to CSS', (WidgetTester tester) async { - final lines = { - Polyline( + final Set lines = { + const Polyline( polylineId: PolylineId('1'), color: Color(0x7FFABADA), ), @@ -359,7 +359,7 @@ void main() { controller.addPolylines(lines); - final line = controller.lines.values.first.line!; + final gmaps.Polyline line = controller.lines.values.first.line!; expect(line.get('strokeColor'), '#fabada'); expect(line.get('strokeOpacity'), closeTo(0.5, _acceptableDelta)); From a51177b00786b86d24bf6593e004ddb14c06785c Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 18 May 2022 17:21:32 -0700 Subject: [PATCH 10/18] Fix test app --- .../google_maps_flutter_web/example/lib/main.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart index d1ba571b5bd0..e93a60e19906 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/lib/main.dart @@ -5,11 +5,14 @@ import 'package:flutter/material.dart'; void main() { - runApp(MyApp()); + runApp(const MyApp()); } /// App for testing class MyApp extends StatefulWidget { + /// Constructor with key + const MyApp({Key? key}) : super(key: key); + @override State createState() => _MyAppState(); } @@ -17,6 +20,6 @@ class MyApp extends StatefulWidget { class _MyAppState extends State { @override Widget build(BuildContext context) { - return Text('Testing... Look at the console output for results!'); + return const Text('Testing... Look at the console output for results!'); } } From 985ebb097e883f9b87a6039438f7c411cb30c1a4 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 18 May 2022 17:22:15 -0700 Subject: [PATCH 11/18] Update google_maps dependency to v6. Remove pedantic. --- .../google_maps_flutter_web/example/pubspec.yaml | 14 +++++++------- .../google_maps_flutter_web/pubspec.yaml | 3 +-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index 95a3d4253440..de81c83b0c8e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -7,21 +7,21 @@ environment: flutter: ">=2.1.0" dependencies: - google_maps_flutter_web: - path: ../ flutter: sdk: flutter + google_maps_flutter_web: + path: ../ dev_dependencies: build_runner: ^2.1.1 - google_maps: ^5.2.0 - google_maps_flutter: # Used for projection_test.dart - path: ../../google_maps_flutter - http: ^0.13.0 - mockito: ^5.0.0 flutter_driver: sdk: flutter flutter_test: sdk: flutter + google_maps: ^6.1.0 + google_maps_flutter: # Used for projection_test.dart + path: ../../google_maps_flutter + http: ^0.13.0 integration_test: sdk: flutter + mockito: ^5.0.0 diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index fcfceb9f5509..21b22c2f9ccd 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -21,9 +21,8 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - google_maps: ^5.2.0 + google_maps: ^6.1.0 google_maps_flutter_platform_interface: ^2.1.2 - pedantic: ^1.10.0 sanitize_html: ^2.0.0 stream_transform: ^2.0.0 From 51c99bc0d0f2b10e8ba5f5ff2d6c2f5d9054bc39 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 18 May 2022 17:29:41 -0700 Subject: [PATCH 12/18] MapEvent -> MapEvent is better --- .../google_maps_controller_test.dart | 8 ++++---- .../google_maps_plugin_test.dart | 20 +++++++++---------- .../integration_test/markers_test.dart | 6 +++--- .../example/integration_test/shapes_test.dart | 12 +++++------ .../lib/src/circles.dart | 4 ++-- .../lib/src/google_maps_controller.dart | 20 +++++++++---------- .../lib/src/google_maps_flutter_web.dart | 6 +++--- .../lib/src/markers.dart | 4 ++-- .../lib/src/polygons.dart | 4 ++-- .../lib/src/polylines.dart | 4 ++-- 10 files changed, 44 insertions(+), 44 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index a27e492986bd..2dcef16db17d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -34,7 +34,7 @@ void main() { group('GoogleMapController', () { const int mapId = 33930; late GoogleMapController controller; - late StreamController> stream; + late StreamController> stream; // Creates a controller with the default mapId and stream controller, and any `options` needed. GoogleMapController _createController({ @@ -59,7 +59,7 @@ void main() { } setUp(() { - stream = StreamController>.broadcast(); + stream = StreamController>.broadcast(); }); group('construct/dispose', () { @@ -219,7 +219,7 @@ void main() { controller.init(); // Trigger events on the map, and verify they've been broadcast to the stream - final Stream> capturedEvents = stream.stream.take(5); + final Stream> capturedEvents = stream.stream.take(5); gmaps.Event.trigger( map, 'click', [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); @@ -228,7 +228,7 @@ void main() { gmaps.Event.trigger(map, 'bounds_changed', []); // Causes 2 events gmaps.Event.trigger(map, 'idle', []); - final List> events = await capturedEvents.toList(); + final List> events = await capturedEvents.toList(); expect(events[0], isA()); expect(events[1], isA()); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart index 61382989812a..9d6ea32ec7c9 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart @@ -338,9 +338,9 @@ void main() { // Verify all event streams are filtered correctly from the main one... group('Event Streams', () { const int mapId = 0; - late StreamController> streamController; + late StreamController> streamController; setUp(() { - streamController = StreamController>.broadcast(); + streamController = StreamController>.broadcast(); when(controller.events) .thenAnswer((Invocation realInvocation) => streamController.stream); plugin.debugSetMapById({mapId: controller}); @@ -348,7 +348,7 @@ void main() { // Dispatches a few events in the global streamController, and expects *only* the passed event to be there. Future _testStreamFiltering( - Stream> stream, MapEvent event) async { + Stream> stream, MapEvent event) async { Timer.run(() { streamController.add(_OtherMapEvent(mapId)); streamController.add(event); @@ -356,7 +356,7 @@ void main() { streamController.close(); }); - final List> events = await stream.toList(); + final List> events = await stream.toList(); expect(events.length, 1); expect(events[0], event); @@ -368,7 +368,7 @@ void main() { final Stream stream = plugin.onCameraMoveStarted(mapId: mapId); - await _testStreamFiltering(stream as Stream>, event as MapEvent); + await _testStreamFiltering(stream, event); }); testWidgets('onCameraMoveStarted', (WidgetTester tester) async { final CameraMoveEvent event = CameraMoveEvent( @@ -387,7 +387,7 @@ void main() { final Stream stream = plugin.onCameraIdle(mapId: mapId); - await _testStreamFiltering(stream as Stream>, event as MapEvent); + await _testStreamFiltering(stream, event); }); // Marker events testWidgets('onMarkerTap', (WidgetTester tester) async { @@ -465,19 +465,19 @@ void main() { final Stream stream = plugin.onTap(mapId: mapId); - await _testStreamFiltering(stream as Stream>, event as MapEvent); + await _testStreamFiltering(stream, event); }); testWidgets('onLongPress', (WidgetTester tester) async { final MapLongPressEvent event = MapLongPressEvent(mapId, const LatLng(43.3608, -5.8425)); final Stream stream = plugin.onLongPress(mapId: mapId); - await _testStreamFiltering(stream as Stream>, event as MapEvent); + await _testStreamFiltering(stream, event); }); }); }); } -class _OtherMapEvent extends MapEvent { - _OtherMapEvent(int mapId) : super(mapId, mapId); +class _OtherMapEvent extends MapEvent { + _OtherMapEvent(int mapId) : super(mapId, null); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart index 2e396b0a74aa..8f6c7f011fed 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart @@ -21,12 +21,12 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('MarkersController', () { - late StreamController> events; + late StreamController> events; late MarkersController controller; late gmaps.GMap map; setUp(() { - events = StreamController>(); + events = StreamController>(); controller = MarkersController(stream: events); map = gmaps.GMap(html.DivElement()); controller.bindToMap(123, map); @@ -212,7 +212,7 @@ void main() { content?.click(); - final MapEvent event = await events.stream.first; + final MapEvent event = await events.stream.first; expect(event, isA()); expect((event as InfoWindowTapEvent).value, equals(const MarkerId('1'))); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart index a0c3478bf4e7..1adb89f188cd 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart @@ -29,11 +29,11 @@ void main() { }); group('CirclesController', () { - late StreamController> events; + late StreamController> events; late CirclesController controller; setUp(() { - events = StreamController>(); + events = StreamController>(); controller = CirclesController(stream: events); controller.bindToMap(123, map); }); @@ -115,11 +115,11 @@ void main() { }); group('PolygonsController', () { - late StreamController> events; + late StreamController> events; late PolygonsController controller; setUp(() { - events = StreamController>(); + events = StreamController>(); controller = PolygonsController(stream: events); controller.bindToMap(123, map); }); @@ -284,11 +284,11 @@ void main() { }); group('PolylinesController', () { - late StreamController> events; + late StreamController> events; late PolylinesController controller; setUp(() { - events = StreamController>(); + events = StreamController>(); controller = PolylinesController(stream: events); controller.bindToMap(123, map); }); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart index 7ad12ddecdae..7398f74afe07 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart @@ -8,7 +8,7 @@ part of google_maps_flutter_web; class CirclesController extends GeometryController { /// Initialize the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. CirclesController({ - required StreamController> stream, + required StreamController> stream, }) : _streamController = stream, _circleIdToController = {}; @@ -16,7 +16,7 @@ class CirclesController extends GeometryController { final Map _circleIdToController; // The stream over which circles broadcast their events - final StreamController> _streamController; + final StreamController> _streamController; /// Returns the cache of [CircleController]s. Test only. @visibleForTesting diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index be356223958e..9c5760ece499 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -14,7 +14,7 @@ class GoogleMapController { /// Initializes the GMap, and the sub-controllers related to it. Wires events. GoogleMapController({ required int mapId, - required StreamController> streamController, + required StreamController> streamController, required CameraPosition initialCameraPosition, Set markers = const {}, Set polygons = const {}, @@ -88,14 +88,14 @@ class GoogleMapController { gmaps.GMap? _googleMap; // The StreamController used by this controller and the geometry ones. - final StreamController> _streamController; + final StreamController> _streamController; /// The StreamController for the events of this Map. Only for integration testing. @visibleForTesting - StreamController> get stream => _streamController; + StreamController> get stream => _streamController; /// The Stream over which this controller broadcasts events. - Stream> get events => _streamController.stream; + Stream> get events => _streamController.stream; // Geometry controllers, for different features of the map. CirclesController? _circlesController; @@ -189,19 +189,19 @@ class GoogleMapController { map.onClick.listen((gmaps.IconMouseEvent event) { assert(event.latLng != null); _streamController.add( - MapTapEvent(_mapId, _gmLatLngToLatLng(event.latLng!)) as MapEvent, + MapTapEvent(_mapId, _gmLatLngToLatLng(event.latLng!)), ); }); map.onRightclick.listen((gmaps.MapMouseEvent event) { assert(event.latLng != null); _streamController.add( - MapLongPressEvent(_mapId, _gmLatLngToLatLng(event.latLng!)) as MapEvent, + MapLongPressEvent(_mapId, _gmLatLngToLatLng(event.latLng!)), ); }); map.onBoundsChanged.listen((void _) { if (!_mapIsMoving) { _mapIsMoving = true; - _streamController.add(CameraMoveStartedEvent(_mapId) as MapEvent); + _streamController.add(CameraMoveStartedEvent(_mapId)); } _streamController.add( CameraMoveEvent(_mapId, _gmViewportToCameraPosition(map)), @@ -209,7 +209,7 @@ class GoogleMapController { }); map.onIdle.listen((void _) { _mapIsMoving = false; - _streamController.add(CameraIdleEvent(_mapId) as MapEvent); + _streamController.add(CameraIdleEvent(_mapId)); }); } @@ -425,7 +425,7 @@ class GoogleMapController { } /// A MapEvent event fired when a [mapId] on web is interactive. -class WebMapReadyEvent extends MapEvent { +class WebMapReadyEvent extends MapEvent { /// Build a WebMapReady Event for the map represented by `mapId`. - WebMapReadyEvent(int mapId) : super(mapId, mapId); + WebMapReadyEvent(int mapId) : super(mapId, null); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart index c076ecf25269..9845ee03aa25 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart @@ -24,7 +24,7 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { } // Convenience getter for a stream of events filtered by their mapId. - Stream> _events(int mapId) => _map(mapId).events; + Stream> _events(int mapId) => _map(mapId).events; // Convenience getter for a map controller by its mapId. GoogleMapController _map(int mapId) { @@ -307,8 +307,8 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { return _mapById[creationId]!.widget!; } - final StreamController> controller = - StreamController>.broadcast(); + final StreamController> controller = + StreamController>.broadcast(); final GoogleMapController mapController = GoogleMapController( initialCameraPosition: initialCameraPosition, diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart index 22b5acd85cd1..909d3d276287 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart @@ -8,7 +8,7 @@ part of google_maps_flutter_web; class MarkersController extends GeometryController { /// Initialize the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. MarkersController({ - required StreamController> stream, + required StreamController> stream, }) : _streamController = stream, _markerIdToController = {}; @@ -16,7 +16,7 @@ class MarkersController extends GeometryController { final Map _markerIdToController; // The stream over which markers broadcast their events - final StreamController> _streamController; + final StreamController> _streamController; /// Returns the cache of [MarkerController]s. Test only. @visibleForTesting diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart index d52aa62c718c..4ba17e2aef83 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart @@ -8,7 +8,7 @@ part of google_maps_flutter_web; class PolygonsController extends GeometryController { /// Initializes the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. PolygonsController({ - required StreamController> stream, + required StreamController> stream, }) : _streamController = stream, _polygonIdToController = {}; @@ -16,7 +16,7 @@ class PolygonsController extends GeometryController { final Map _polygonIdToController; // The stream over which polygons broadcast events - final StreamController> _streamController; + final StreamController> _streamController; /// Returns the cache of [PolygonController]s. Test only. @visibleForTesting diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart index 4706c438ef36..d5333c8d18a3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart @@ -8,7 +8,7 @@ part of google_maps_flutter_web; class PolylinesController extends GeometryController { /// Initializes the cache. The [StreamController] comes from the [GoogleMapController], and is shared with other controllers. PolylinesController({ - required StreamController> stream, + required StreamController> stream, }) : _streamController = stream, _polylineIdToController = {}; @@ -16,7 +16,7 @@ class PolylinesController extends GeometryController { final Map _polylineIdToController; // The stream over which polylines broadcast their events - final StreamController> _streamController; + final StreamController> _streamController; /// Returns the cache of [PolylineContrller]s. Test only. @visibleForTesting From 1b8e5e20c4721a417046f83268c9b72ae901b8fd Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 18 May 2022 17:54:55 -0700 Subject: [PATCH 13/18] Fix tests --- .../lib/src/convert.dart | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index cf2153acb909..821db790f6b3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -63,10 +63,10 @@ gmaps.MapOptions _rawOptionsToGmapsOptions(Map rawOptions) { } if (rawOptions['minMaxZoomPreference'] != null) { - final List minMaxPreference = rawOptions['minMaxZoomPreference']! as List; + final List minMaxPreference = rawOptions['minMaxZoomPreference']! as List; options - ..minZoom = minMaxPreference[0] - ..maxZoom = minMaxPreference[1]; + ..minZoom = minMaxPreference[0] as num? + ..maxZoom = minMaxPreference[1] as num?; } if (rawOptions['cameraTargetBounds'] != null) { @@ -135,7 +135,7 @@ List _mapStyles(String? mapStyleJson) { if (value is Map && _isJsonMapStyle(value as Map)) { List stylers = []; if (value['stylers'] != null) { - stylers = (value['stylers']! as List).map((Object e) => jsify(e)).toList(); + stylers = (value['stylers']! as List).map((Object? e) => e != null ? jsify(e) : null).toList(); } return gmaps.MapTypeStyle() ..elementType = value['elementType'] as String? @@ -232,7 +232,7 @@ gmaps.MarkerOptions _markerOptionsFromMarker( Marker marker, gmaps.Marker? currentMarker, ) { - final List iconConfig = marker.icon.toJson() as List; + final List iconConfig = marker.icon.toJson() as List; gmaps.Icon? icon; if (iconConfig != null) { @@ -242,19 +242,19 @@ gmaps.MarkerOptions _markerOptionsFromMarker( // already encoded in the iconConfig[1] icon = gmaps.Icon() - ..url = ui.webOnlyAssetManager.getAssetUrl(iconConfig[1] as String); + ..url = ui.webOnlyAssetManager.getAssetUrl(iconConfig[1]! as String); // iconConfig[3] may contain the [width, height] of the image, if passed! if (iconConfig.length >= 4 && iconConfig[3] != null) { - final List rawIconSize = iconConfig[3] as List; - final gmaps.Size size = gmaps.Size(rawIconSize[0], rawIconSize[1]); + final List rawIconSize = iconConfig[3]! as List; + final gmaps.Size size = gmaps.Size(rawIconSize[0] as num?, rawIconSize[1] as num?); icon ..size = size ..scaledSize = size; } } else if (iconConfig[0] == 'fromBytes') { // Grab the bytes, and put them into a blob - final List bytes = iconConfig[1] as List; + final List bytes = iconConfig[1]! as List; final Blob blob = Blob([bytes]); // Let the browser figure out the encoding icon = gmaps.Icon()..url = Url.createObjectUrlFromBlob(blob); } From d9f997c92239aaafa5168e9faecd7c60cac60ef5 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 18 May 2022 17:55:09 -0700 Subject: [PATCH 14/18] Regenerate mocks with latest mockito. --- .../google_maps_controller_test.mocks.dart | 11 ++--------- .../google_maps_plugin_test.mocks.dart | 17 ++++++++--------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart index 530707c6c328..9565935bd8ed 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.mocks.dart @@ -1,4 +1,4 @@ -// Mocks generated by Mockito 5.0.16 from annotations +// Mocks generated by Mockito 5.2.0 from annotations // in google_maps_flutter_web_integration_tests/integration_test/google_maps_controller_test.dart. // Do not manually edit this file. @@ -8,6 +8,7 @@ import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platf import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' as _i3; import 'package:mockito/mockito.dart' as _i1; +// ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters // ignore_for_file: comment_references @@ -58,8 +59,6 @@ class MockCirclesController extends _i1.Mock implements _i3.CirclesController { void bindToMap(int? mapId, _i2.GMap? googleMap) => super.noSuchMethod(Invocation.method(#bindToMap, [mapId, googleMap]), returnValueForMissingStub: null); - @override - String toString() => super.toString(); } /// A class which mocks [PolygonsController]. @@ -102,8 +101,6 @@ class MockPolygonsController extends _i1.Mock void bindToMap(int? mapId, _i2.GMap? googleMap) => super.noSuchMethod(Invocation.method(#bindToMap, [mapId, googleMap]), returnValueForMissingStub: null); - @override - String toString() => super.toString(); } /// A class which mocks [PolylinesController]. @@ -146,8 +143,6 @@ class MockPolylinesController extends _i1.Mock void bindToMap(int? mapId, _i2.GMap? googleMap) => super.noSuchMethod(Invocation.method(#bindToMap, [mapId, googleMap]), returnValueForMissingStub: null); - @override - String toString() => super.toString(); } /// A class which mocks [MarkersController]. @@ -201,6 +196,4 @@ class MockMarkersController extends _i1.Mock implements _i3.MarkersController { void bindToMap(int? mapId, _i2.GMap? googleMap) => super.noSuchMethod(Invocation.method(#bindToMap, [mapId, googleMap]), returnValueForMissingStub: null); - @override - String toString() => super.toString(); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart index d2df11c6ffa9..bbc92ffc6096 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart @@ -1,4 +1,4 @@ -// Mocks generated by Mockito 5.0.16 from annotations +// Mocks generated by Mockito 5.2.0 from annotations // in google_maps_flutter_web_integration_tests/integration_test/google_maps_plugin_test.dart. // Do not manually edit this file. @@ -9,6 +9,7 @@ import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platf import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' as _i4; import 'package:mockito/mockito.dart' as _i1; +// ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters // ignore_for_file: comment_references @@ -34,15 +35,15 @@ class _FakeLatLng_3 extends _i1.Fake implements _i3.LatLng {} class MockGoogleMapController extends _i1.Mock implements _i4.GoogleMapController { @override - _i2.StreamController<_i3.MapEvent> get stream => + _i2.StreamController<_i3.MapEvent> get stream => (super.noSuchMethod(Invocation.getter(#stream), - returnValue: _FakeStreamController_0<_i3.MapEvent>()) - as _i2.StreamController<_i3.MapEvent>); + returnValue: _FakeStreamController_0<_i3.MapEvent>()) + as _i2.StreamController<_i3.MapEvent>); @override - _i2.Stream<_i3.MapEvent> get events => + _i2.Stream<_i3.MapEvent> get events => (super.noSuchMethod(Invocation.getter(#events), - returnValue: Stream<_i3.MapEvent>.empty()) - as _i2.Stream<_i3.MapEvent>); + returnValue: Stream<_i3.MapEvent>.empty()) + as _i2.Stream<_i3.MapEvent>); @override bool get isInitialized => (super.noSuchMethod(Invocation.getter(#isInitialized), returnValue: false) @@ -126,6 +127,4 @@ class MockGoogleMapController extends _i1.Mock @override void dispose() => super.noSuchMethod(Invocation.method(#dispose, []), returnValueForMissingStub: null); - @override - String toString() => super.toString(); } From d96ac568d88d897233a02988005d5977f7da0a43 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 18 May 2022 18:16:30 -0700 Subject: [PATCH 15/18] dart format . --- .../google_maps_controller_test.dart | 83 ++++++++--- .../google_maps_plugin_test.dart | 136 +++++++++++++----- .../example/integration_test/marker_test.dart | 30 ++-- .../integration_test/markers_test.dart | 21 +-- .../example/integration_test/shape_test.dart | 27 ++-- .../example/integration_test/shapes_test.dart | 9 +- .../lib/src/circles.dart | 6 +- .../lib/src/convert.dart | 82 +++++++---- .../lib/src/google_maps_controller.dart | 7 +- .../lib/src/google_maps_flutter_web.dart | 5 +- .../lib/src/markers.dart | 21 +-- .../lib/src/polygons.dart | 8 +- .../lib/src/polylines.dart | 8 +- 13 files changed, 307 insertions(+), 136 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index 2dcef16db17d..17fdd81df645 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -143,7 +143,12 @@ void main() { controller.dispose(); expect(() { - controller.updateCircles(CircleUpdates.from({}, {})); + controller.updateCircles( + CircleUpdates.from( + {}, + {}, + ), + ); }, throwsAssertionError); }); @@ -152,7 +157,12 @@ void main() { controller.dispose(); expect(() { - controller.updatePolygons(PolygonUpdates.from({}, {})); + controller.updatePolygons( + PolygonUpdates.from( + {}, + {}, + ), + ); }, throwsAssertionError); }); @@ -161,7 +171,12 @@ void main() { controller.dispose(); expect(() { - controller.updatePolylines(PolylineUpdates.from({}, {})); + controller.updatePolylines( + PolylineUpdates.from( + {}, + {}, + ), + ); }, throwsAssertionError); }); @@ -170,7 +185,12 @@ void main() { controller.dispose(); expect(() { - controller.updateMarkers(MarkerUpdates.from({}, {})); + controller.updateMarkers( + MarkerUpdates.from( + {}, + {}, + ), + ); }, throwsAssertionError); expect(() { @@ -222,10 +242,17 @@ void main() { final Stream> capturedEvents = stream.stream.take(5); gmaps.Event.trigger( - map, 'click', [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); - gmaps.Event.trigger(map, 'rightclick', - [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); - gmaps.Event.trigger(map, 'bounds_changed', []); // Causes 2 events + map, + 'click', + [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)], + ); + gmaps.Event.trigger( + map, + 'rightclick', + [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)], + ); + // The following line causes 2 events + gmaps.Event.trigger(map, 'bounds_changed', []); gmaps.Event.trigger(map, 'idle', []); final List> events = await capturedEvents.toList(); @@ -315,10 +342,12 @@ void main() { verify(circles.addCircles(captureAny)).captured[0] as Set; final Set capturedMarkers = verify(markers.addMarkers(captureAny)).captured[0] as Set; - final Set capturedPolygons = verify(polygons.addPolygons(captureAny)) - .captured[0] as Set; - final Set capturedPolylines = verify(polylines.addPolylines(captureAny)) - .captured[0] as Set; + final Set capturedPolygons = + verify(polygons.addPolygons(captureAny)).captured[0] + as Set; + final Set capturedPolylines = + verify(polylines.addPolylines(captureAny)).captured[0] + as Set; expect(capturedCircles.first.circleId.value, 'circle-1'); expect(capturedCircles.first.zIndex, 1234); @@ -360,7 +389,8 @@ void main() { 'mapType': 2, 'zoomControlsEnabled': true, }); - controller.debugSetOverrides(createMap: (_, gmaps.MapOptions options) { + controller.debugSetOverrides( + createMap: (_, gmaps.MapOptions options) { capturedOptions = options; return map; }); @@ -380,7 +410,8 @@ void main() { controller = _createController(options: { 'scrollGesturesEnabled': false, }); - controller.debugSetOverrides(createMap: (_, gmaps.MapOptions options) { + controller.debugSetOverrides( + createMap: (_, gmaps.MapOptions options) { capturedOptions = options; return map; }); @@ -398,7 +429,8 @@ void main() { controller = _createController(options: { 'zoomGesturesEnabled': false, }); - controller.debugSetOverrides(createMap: (_, gmaps.MapOptions options) { + controller.debugSetOverrides( + createMap: (_, gmaps.MapOptions options) { capturedOptions = options; return map; }); @@ -422,7 +454,8 @@ void main() { ), ); - controller.debugSetOverrides(createMap: (_, gmaps.MapOptions options) { + controller.debugSetOverrides( + createMap: (_, gmaps.MapOptions options) { capturedOptions = options; return map; }); @@ -516,8 +549,12 @@ void main() { group('moveCamera', () { testWidgets('newLatLngZoom', (WidgetTester tester) async { - await controller - .moveCamera(CameraUpdate.newLatLngZoom(const LatLng(19, 26), 12,),); + await controller.moveCamera( + CameraUpdate.newLatLngZoom( + const LatLng(19, 26), + 12, + ), + ); final gmaps.LatLng gmCenter = map.center!; @@ -629,7 +666,10 @@ void main() { }; final Set current = { - const Polyline(polylineId: PolylineId('to-be-updated'), visible: false), + const Polyline( + polylineId: PolylineId('to-be-updated'), + visible: false, + ), const Polyline(polylineId: PolylineId('to-be-added')), }; @@ -642,7 +682,10 @@ void main() { const Polyline(polylineId: PolylineId('to-be-added')), })); verify(mock.changePolylines({ - const Polyline(polylineId: PolylineId('to-be-updated'), visible: false), + const Polyline( + polylineId: PolylineId('to-be-updated'), + visible: false, + ), })); }); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart index 9d6ea32ec7c9..f0fd5a232e00 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart @@ -69,12 +69,14 @@ void main() { group('buildView', () { const int testMapId = 33930; - const CameraPosition initialCameraPosition = CameraPosition(target: LatLng(0, 0)); + const CameraPosition initialCameraPosition = + CameraPosition(target: LatLng(0, 0)); testWidgets( 'returns an HtmlElementView and caches the controller for later', (WidgetTester tester) async { - final Map cache = {}; + final Map cache = + {}; plugin.debugSetMapById(cache); final Widget widget = plugin.buildView( @@ -105,9 +107,12 @@ void main() { testWidgets('returns cached instance if it already exists', (WidgetTester tester) async { - const HtmlElementView expected = HtmlElementView(viewType: 'only-for-testing'); + const HtmlElementView expected = + HtmlElementView(viewType: 'only-for-testing'); when(controller.widget).thenReturn(expected); - plugin.debugSetMapById({testMapId: controller}); + plugin.debugSetMapById({ + testMapId: controller, + }); final Widget widget = plugin.buildView( testMapId, @@ -121,7 +126,8 @@ void main() { testWidgets( 'asynchronously reports onPlatformViewCreated the first time it happens', (WidgetTester tester) async { - final Map cache = {}; + final Map cache = + {}; plugin.debugSetMapById(cache); plugin.buildView( @@ -173,7 +179,8 @@ void main() { verify(controller.updateRawOptions(captureThat(isMap))).captured[0]; expect(captured, contains('styles')); - final List styles = captured['styles'] as List; + final List styles = + captured['styles'] as List; expect(styles.length, 1); // Let's peek inside the styles... final gmaps.MapTypeStyle style = styles[0]; @@ -191,13 +198,17 @@ void main() { }); // Options testWidgets('updateTileOverlays', (WidgetTester tester) async { - final Future update = - plugin.updateTileOverlays(mapId: mapId, newTileOverlays: {}); + final Future update = plugin.updateTileOverlays( + mapId: mapId, + newTileOverlays: {}, + ); expect(update, completion(null)); }); testWidgets('updateTileOverlays', (WidgetTester tester) async { - final Future update = - plugin.clearTileCache(const TileOverlayId('any'), mapId: mapId); + final Future update = plugin.clearTileCache( + const TileOverlayId('any'), + mapId: mapId, + ); expect(update, completion(null)); }); }); @@ -211,7 +222,9 @@ void main() { }); // Options testWidgets('updateMapOptions', (WidgetTester tester) async { - final Map expectedMapOptions = {'someOption': 12345}; + final Map expectedMapOptions = { + 'someOption': 12345 + }; await plugin.updateMapOptions(expectedMapOptions, mapId: mapId); @@ -219,28 +232,40 @@ void main() { }); // Geometry testWidgets('updateMarkers', (WidgetTester tester) async { - final MarkerUpdates expectedUpdates = MarkerUpdates.from({}, {}); + final MarkerUpdates expectedUpdates = MarkerUpdates.from( + {}, + {}, + ); await plugin.updateMarkers(expectedUpdates, mapId: mapId); verify(controller.updateMarkers(expectedUpdates)); }); testWidgets('updatePolygons', (WidgetTester tester) async { - final PolygonUpdates expectedUpdates = PolygonUpdates.from({}, {}); + final PolygonUpdates expectedUpdates = PolygonUpdates.from( + {}, + {}, + ); await plugin.updatePolygons(expectedUpdates, mapId: mapId); verify(controller.updatePolygons(expectedUpdates)); }); testWidgets('updatePolylines', (WidgetTester tester) async { - final PolylineUpdates expectedUpdates = PolylineUpdates.from({}, {}); + final PolylineUpdates expectedUpdates = PolylineUpdates.from( + {}, + {}, + ); await plugin.updatePolylines(expectedUpdates, mapId: mapId); verify(controller.updatePolylines(expectedUpdates)); }); testWidgets('updateCircles', (WidgetTester tester) async { - final CircleUpdates expectedUpdates = CircleUpdates.from({}, {}); + final CircleUpdates expectedUpdates = CircleUpdates.from( + {}, + {}, + ); await plugin.updateCircles(expectedUpdates, mapId: mapId); @@ -248,16 +273,18 @@ void main() { }); // Camera testWidgets('animateCamera', (WidgetTester tester) async { - final CameraUpdate expectedUpdates = - CameraUpdate.newLatLng(const LatLng(43.3626, -5.8433)); + final CameraUpdate expectedUpdates = CameraUpdate.newLatLng( + const LatLng(43.3626, -5.8433), + ); await plugin.animateCamera(expectedUpdates, mapId: mapId); verify(controller.moveCamera(expectedUpdates)); }); testWidgets('moveCamera', (WidgetTester tester) async { - final CameraUpdate expectedUpdates = - CameraUpdate.newLatLng(const LatLng(43.3628, -5.8478)); + final CameraUpdate expectedUpdates = CameraUpdate.newLatLng( + const LatLng(43.3628, -5.8478), + ); await plugin.moveCamera(expectedUpdates, mapId: mapId); @@ -296,9 +323,9 @@ void main() { }); testWidgets('getLatLng', (WidgetTester tester) async { - when(controller.getLatLng(any)) - .thenAnswer((_) async => const LatLng(43.3613, -5.8499) // fake return - ); + when(controller.getLatLng(any)).thenAnswer( + (_) async => const LatLng(43.3613, -5.8499) // fake return + ); const ScreenCoordinate coordinates = ScreenCoordinate(x: 19, y: 26); @@ -366,7 +393,8 @@ void main() { testWidgets('onCameraMoveStarted', (WidgetTester tester) async { final CameraMoveStartedEvent event = CameraMoveStartedEvent(mapId); - final Stream stream = plugin.onCameraMoveStarted(mapId: mapId); + final Stream stream = + plugin.onCameraMoveStarted(mapId: mapId); await _testStreamFiltering(stream, event); }); @@ -378,29 +406,38 @@ void main() { ), ); - final Stream stream = plugin.onCameraMove(mapId: mapId); + final Stream stream = + plugin.onCameraMove(mapId: mapId); await _testStreamFiltering(stream, event); }); testWidgets('onCameraIdle', (WidgetTester tester) async { final CameraIdleEvent event = CameraIdleEvent(mapId); - final Stream stream = plugin.onCameraIdle(mapId: mapId); + final Stream stream = + plugin.onCameraIdle(mapId: mapId); await _testStreamFiltering(stream, event); }); // Marker events testWidgets('onMarkerTap', (WidgetTester tester) async { - final MarkerTapEvent event = MarkerTapEvent(mapId, const MarkerId('test-123')); + final MarkerTapEvent event = MarkerTapEvent( + mapId, + const MarkerId('test-123'), + ); final Stream stream = plugin.onMarkerTap(mapId: mapId); await _testStreamFiltering(stream, event); }); testWidgets('onInfoWindowTap', (WidgetTester tester) async { - final InfoWindowTapEvent event = InfoWindowTapEvent(mapId, const MarkerId('test-123')); + final InfoWindowTapEvent event = InfoWindowTapEvent( + mapId, + const MarkerId('test-123'), + ); - final Stream stream = plugin.onInfoWindowTap(mapId: mapId); + final Stream stream = + plugin.onInfoWindowTap(mapId: mapId); await _testStreamFiltering(stream, event); }); @@ -411,7 +448,8 @@ void main() { const MarkerId('test-123'), ); - final Stream stream = plugin.onMarkerDragStart(mapId: mapId); + final Stream stream = + plugin.onMarkerDragStart(mapId: mapId); await _testStreamFiltering(stream, event); }); @@ -422,7 +460,8 @@ void main() { const MarkerId('test-123'), ); - final Stream stream = plugin.onMarkerDrag(mapId: mapId); + final Stream stream = + plugin.onMarkerDrag(mapId: mapId); await _testStreamFiltering(stream, event); }); @@ -433,27 +472,39 @@ void main() { const MarkerId('test-123'), ); - final Stream stream = plugin.onMarkerDragEnd(mapId: mapId); + final Stream stream = + plugin.onMarkerDragEnd(mapId: mapId); await _testStreamFiltering(stream, event); }); // Geometry testWidgets('onPolygonTap', (WidgetTester tester) async { - final PolygonTapEvent event = PolygonTapEvent(mapId, const PolygonId('test-123')); + final PolygonTapEvent event = PolygonTapEvent( + mapId, + const PolygonId('test-123'), + ); - final Stream stream = plugin.onPolygonTap(mapId: mapId); + final Stream stream = + plugin.onPolygonTap(mapId: mapId); await _testStreamFiltering(stream, event); }); testWidgets('onPolylineTap', (WidgetTester tester) async { - final PolylineTapEvent event = PolylineTapEvent(mapId, const PolylineId('test-123')); + final PolylineTapEvent event = PolylineTapEvent( + mapId, + const PolylineId('test-123'), + ); - final Stream stream = plugin.onPolylineTap(mapId: mapId); + final Stream stream = + plugin.onPolylineTap(mapId: mapId); await _testStreamFiltering(stream, event); }); testWidgets('onCircleTap', (WidgetTester tester) async { - final CircleTapEvent event = CircleTapEvent(mapId, const CircleId('test-123')); + final CircleTapEvent event = CircleTapEvent( + mapId, + const CircleId('test-123'), + ); final Stream stream = plugin.onCircleTap(mapId: mapId); @@ -461,16 +512,23 @@ void main() { }); // Map taps testWidgets('onTap', (WidgetTester tester) async { - final MapTapEvent event = MapTapEvent(mapId, const LatLng(43.3597, -5.8458)); + final MapTapEvent event = MapTapEvent( + mapId, + const LatLng(43.3597, -5.8458), + ); final Stream stream = plugin.onTap(mapId: mapId); await _testStreamFiltering(stream, event); }); testWidgets('onLongPress', (WidgetTester tester) async { - final MapLongPressEvent event = MapLongPressEvent(mapId, const LatLng(43.3608, -5.8425)); + final MapLongPressEvent event = MapLongPressEvent( + mapId, + const LatLng(43.3608, -5.8425), + ); - final Stream stream = plugin.onLongPress(mapId: mapId); + final Stream stream = + plugin.onLongPress(mapId: mapId); await _testStreamFiltering(stream, event); }); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart index cb53c5db6907..e07ade03bba3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/marker_test.dart @@ -76,7 +76,10 @@ void main() { // Trigger a drag end event... gmaps.Event.trigger( - marker, 'drag', [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); + marker, + 'drag', + [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)], + ); expect(await methodCalled, isTrue); }); @@ -85,15 +88,19 @@ void main() { MarkerController(marker: marker, onDragEnd: onDragEnd); // Trigger a drag end event... - gmaps.Event.trigger(marker, 'dragend', - [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)]); + gmaps.Event.trigger( + marker, + 'dragend', + [gmaps.MapMouseEvent()..latLng = gmaps.LatLng(0, 0)], + ); expect(await methodCalled, isTrue); }); testWidgets('update', (WidgetTester tester) async { final MarkerController controller = MarkerController(marker: marker); - final gmaps.MarkerOptions options = gmaps.MarkerOptions()..draggable = true; + final gmaps.MarkerOptions options = gmaps.MarkerOptions() + ..draggable = true; expect(marker.draggable, isNull); @@ -115,8 +122,10 @@ void main() { final gmaps.InfoWindow infoWindow = gmaps.InfoWindow(); final gmaps.GMap map = gmaps.GMap(html.DivElement()); marker.set('map', map); - final MarkerController controller = - MarkerController(marker: marker, infoWindow: infoWindow); + final MarkerController controller = MarkerController( + marker: marker, + infoWindow: infoWindow, + ); controller.showInfoWindow(); @@ -128,8 +137,10 @@ void main() { final gmaps.InfoWindow infoWindow = gmaps.InfoWindow(); final gmaps.GMap map = gmaps.GMap(html.DivElement()); marker.set('map', map); - final MarkerController controller = - MarkerController(marker: marker, infoWindow: infoWindow); + final MarkerController controller = MarkerController( + marker: marker, + infoWindow: infoWindow, + ); controller.hideInfoWindow(); @@ -155,7 +166,8 @@ void main() { testWidgets('cannot call update after remove', (WidgetTester tester) async { - final gmaps.MarkerOptions options = gmaps.MarkerOptions()..draggable = true; + final gmaps.MarkerOptions options = gmaps.MarkerOptions() + ..draggable = true; controller.remove(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart index 8f6c7f011fed..90195ec6397b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/markers_test.dart @@ -52,7 +52,8 @@ void main() { }; controller.addMarkers(markers); - expect(controller.markers[const MarkerId('1')]?.marker?.draggable, isFalse); + expect( + controller.markers[const MarkerId('1')]?.marker?.draggable, isFalse); // Update the marker with radius 10 final Set updatedMarkers = { @@ -61,7 +62,8 @@ void main() { controller.changeMarkers(updatedMarkers); expect(controller.markers.length, 1); - expect(controller.markers[const MarkerId('1')]?.marker?.draggable, isTrue); + expect( + controller.markers[const MarkerId('1')]?.marker?.draggable, isTrue); }); testWidgets('removeMarkers', (WidgetTester tester) async { @@ -145,7 +147,9 @@ void main() { final Uint8List bytes = const Base64Decoder().convert(iconImageBase64); final Set markers = { Marker( - markerId: const MarkerId('1'), icon: BitmapDescriptor.fromBytes(bytes)), + markerId: const MarkerId('1'), + icon: BitmapDescriptor.fromBytes(bytes), + ), }; controller.addMarkers(markers); @@ -183,13 +187,14 @@ void main() { controller.addMarkers(markers); expect(controller.markers.length, 1); - final html.HtmlElement? content = controller.markers[const MarkerId('1')]?.infoWindow?.content - as html.HtmlElement?; + final html.HtmlElement? content = controller.markers[const MarkerId('1')] + ?.infoWindow?.content as html.HtmlElement?; expect(content?.innerHtml, contains('title for test')); expect( content?.innerHtml, contains( - 'Go to Google >>>')); + 'Go to Google >>>', + )); }); // https://github.com/flutter/flutter/issues/67289 @@ -207,8 +212,8 @@ void main() { controller.addMarkers(markers); expect(controller.markers.length, 1); - final html.HtmlElement? content = controller.markers[const MarkerId('1')]?.infoWindow?.content - as html.HtmlElement?; + final html.HtmlElement? content = controller.markers[const MarkerId('1')] + ?.infoWindow?.content as html.HtmlElement?; content?.click(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart index fa9f55b9c3f0..d1426760ceae 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shape_test.dart @@ -50,7 +50,8 @@ void main() { testWidgets('update', (WidgetTester tester) async { final CircleController controller = CircleController(circle: circle); - final gmaps.CircleOptions options = gmaps.CircleOptions()..draggable = true; + final gmaps.CircleOptions options = gmaps.CircleOptions() + ..draggable = true; expect(circle.draggable, isNull); @@ -74,7 +75,8 @@ void main() { testWidgets('cannot call update after remove', (WidgetTester tester) async { - final gmaps.CircleOptions options = gmaps.CircleOptions()..draggable = true; + final gmaps.CircleOptions options = gmaps.CircleOptions() + ..draggable = true; controller.remove(); @@ -104,7 +106,8 @@ void main() { testWidgets('update', (WidgetTester tester) async { final PolygonController controller = PolygonController(polygon: polygon); - final gmaps.PolygonOptions options = gmaps.PolygonOptions()..draggable = true; + final gmaps.PolygonOptions options = gmaps.PolygonOptions() + ..draggable = true; expect(polygon.draggable, isNull); @@ -128,7 +131,8 @@ void main() { testWidgets('cannot call update after remove', (WidgetTester tester) async { - final gmaps.PolygonOptions options = gmaps.PolygonOptions()..draggable = true; + final gmaps.PolygonOptions options = gmaps.PolygonOptions() + ..draggable = true; controller.remove(); @@ -148,7 +152,10 @@ void main() { testWidgets('onTap gets called', (WidgetTester tester) async { PolylineController( - polyline: polyline, consumeTapEvents: true, onTap: onTap); + polyline: polyline, + consumeTapEvents: true, + onTap: onTap, + ); // Trigger a click event... gmaps.Event.trigger(polyline, 'click', [gmaps.MapMouseEvent()]); @@ -158,8 +165,11 @@ void main() { }); testWidgets('update', (WidgetTester tester) async { - final PolylineController controller = PolylineController(polyline: polyline); - final gmaps.PolylineOptions options = gmaps.PolylineOptions()..draggable = true; + final PolylineController controller = PolylineController( + polyline: polyline, + ); + final gmaps.PolylineOptions options = gmaps.PolylineOptions() + ..draggable = true; expect(polyline.draggable, isNull); @@ -183,7 +193,8 @@ void main() { testWidgets('cannot call update after remove', (WidgetTester tester) async { - final gmaps.PolylineOptions options = gmaps.PolylineOptions()..draggable = true; + final gmaps.PolylineOptions options = gmaps.PolylineOptions() + ..draggable = true; controller.remove(); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart index 1adb89f188cd..b9bc2d371c9b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/shapes_test.dart @@ -144,7 +144,8 @@ void main() { }; controller.addPolygons(polygons); - expect(controller.polygons[const PolygonId('1')]?.polygon?.visible, isTrue); + expect( + controller.polygons[const PolygonId('1')]?.polygon?.visible, isTrue); // Update the polygon final Set updatedPolygons = { @@ -153,7 +154,8 @@ void main() { controller.changePolygons(updatedPolygons); expect(controller.polygons.length, 1); - expect(controller.polygons[const PolygonId('1')]?.polygon?.visible, isFalse); + expect( + controller.polygons[const PolygonId('1')]?.polygon?.visible, isFalse); }); testWidgets('removePolygons', (WidgetTester tester) async { @@ -275,7 +277,8 @@ void main() { controller.addPolygons(polygons); - final gmaps.MVCArray?> paths = controller.polygons.values.first.polygon!.paths!; + final gmaps.MVCArray?> paths = + controller.polygons.values.first.polygon!.paths!; expect(paths.getAt(1)?.getAt(0)?.lat, 28.745); expect(paths.getAt(1)?.getAt(1)?.lat, 29.57); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart index 7398f74afe07..bc6eac14200f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/circles.dart @@ -35,8 +35,7 @@ class CirclesController extends GeometryController { } final gmaps.CircleOptions circleOptions = _circleOptionsFromCircle(circle); - final gmaps.Circle gmCircle = gmaps.Circle(circleOptions) - ..map = googleMap; + final gmaps.Circle gmCircle = gmaps.Circle(circleOptions)..map = googleMap; final CircleController controller = CircleController( circle: gmCircle, consumeTapEvents: circle.consumeTapEvents, @@ -52,7 +51,8 @@ class CirclesController extends GeometryController { } void _changeCircle(Circle circle) { - final CircleController? circleController = _circleIdToController[circle.circleId]; + final CircleController? circleController = + _circleIdToController[circle.circleId]; circleController?.update(_circleOptionsFromCircle(circle)); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 821db790f6b3..7dd5395f0c94 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -63,7 +63,8 @@ gmaps.MapOptions _rawOptionsToGmapsOptions(Map rawOptions) { } if (rawOptions['minMaxZoomPreference'] != null) { - final List minMaxPreference = rawOptions['minMaxZoomPreference']! as List; + final List minMaxPreference = + rawOptions['minMaxZoomPreference']! as List; options ..minZoom = minMaxPreference[0] as num? ..maxZoom = minMaxPreference[1] as num?; @@ -132,18 +133,20 @@ List _mapStyles(String? mapStyleJson) { List styles = []; if (mapStyleJson != null) { styles = (json.decode(mapStyleJson, reviver: (Object? key, Object? value) { - if (value is Map && _isJsonMapStyle(value as Map)) { - List stylers = []; - if (value['stylers'] != null) { - stylers = (value['stylers']! as List).map((Object? e) => e != null ? jsify(e) : null).toList(); - } - return gmaps.MapTypeStyle() - ..elementType = value['elementType'] as String? - ..featureType = value['featureType'] as String? - ..stylers = stylers; - } - return value; - }) as List) + if (value is Map && _isJsonMapStyle(value as Map)) { + List stylers = []; + if (value['stylers'] != null) { + stylers = (value['stylers']! as List) + .map((Object? e) => e != null ? jsify(e) : null) + .toList(); + } + return gmaps.MapTypeStyle() + ..elementType = value['elementType'] as String? + ..featureType = value['featureType'] as String? + ..stylers = stylers; + } + return value; + }) as List) .where((Object? element) => element != null) .cast() .toList(); @@ -247,7 +250,10 @@ gmaps.MarkerOptions _markerOptionsFromMarker( // iconConfig[3] may contain the [width, height] of the image, if passed! if (iconConfig.length >= 4 && iconConfig[3] != null) { final List rawIconSize = iconConfig[3]! as List; - final gmaps.Size size = gmaps.Size(rawIconSize[0] as num?, rawIconSize[1] as num?); + final gmaps.Size size = gmaps.Size( + rawIconSize[0] as num?, + rawIconSize[1] as num?, + ); icon ..size = size ..scaledSize = size; @@ -255,7 +261,8 @@ gmaps.MarkerOptions _markerOptionsFromMarker( } else if (iconConfig[0] == 'fromBytes') { // Grab the bytes, and put them into a blob final List bytes = iconConfig[1]! as List; - final Blob blob = Blob([bytes]); // Let the browser figure out the encoding + // Create a Blob from bytes, but let the browser figure out the encoding + final Blob blob = Blob([bytes]); icon = gmaps.Icon()..url = Url.createObjectUrlFromBlob(blob); } } @@ -302,7 +309,12 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon( for (int i = 0; i < polygon.holes.length; i++) { final List hole = polygon.holes[i]; - final List correctHole = _ensureHoleHasReverseWinding(hole, isClockwisePolygon, holeId: i, polygonId: polygon.polygonId); + final List correctHole = _ensureHoleHasReverseWinding( + hole, + isClockwisePolygon, + holeId: i, + polygonId: polygon.polygonId, + ); paths.add(correctHole); } @@ -318,18 +330,22 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon( ..geodesic = polygon.geodesic; } -List _ensureHoleHasReverseWinding(List hole, bool polyIsClockwise, {int? holeId, PolygonId? polygonId}) { +List _ensureHoleHasReverseWinding( + List hole, + bool polyIsClockwise, { + int? holeId, + PolygonId? polygonId, +}) { List holePath = hole.map(_latLngToGmLatLng).toList(); final bool holeIsClockwise = _isPolygonClockwise(holePath); if (holeIsClockwise == polyIsClockwise) { holePath = holePath.reversed.toList(); - if (kDebugMode) { - print( - 'Hole [$holeId] in Polygon [${polygonId?.value}] has been reversed.' - ' Ensure holes in polygons are "wound in the opposite direction to the outer path."' - ' More info: https://github.com/flutter/flutter/issues/74096'); - } + if (kDebugMode) { + print('Hole [$holeId] in Polygon [${polygonId?.value}] has been reversed.' + ' Ensure holes in polygons are "wound in the opposite direction to the outer path."' + ' More info: https://github.com/flutter/flutter/issues/74096'); + } } return holePath; @@ -384,7 +400,12 @@ void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { case 'newCameraPosition': map.heading = json[1]['bearing'] as num?; map.zoom = json[1]['zoom'] as num?; - map.panTo(gmaps.LatLng(json[1]['target'][0] as num?, json[1]['target'][1] as num?)); + map.panTo( + gmaps.LatLng( + json[1]['target'][0] as num?, + json[1]['target'][1] as num?, + ), + ); map.tilt = json[1]['tilt'] as num?; break; case 'newLatLng': @@ -395,9 +416,12 @@ void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { map.panTo(gmaps.LatLng(json[1][0] as num?, json[1][1] as num?)); break; case 'newLatLngBounds': - map.fitBounds(gmaps.LatLngBounds( + map.fitBounds( + gmaps.LatLngBounds( gmaps.LatLng(json[1][0][0] as num?, json[1][0][1] as num?), - gmaps.LatLng(json[1][1][0] as num?, json[1][1][1] as num?))); + gmaps.LatLng(json[1][1][0] as num?, json[1][1][1] as num?), + ), + ); // padding = json[2]; // Needs package:google_maps ^4.0.0 to adjust the padding in fitBounds break; @@ -408,11 +432,13 @@ void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) { gmaps.LatLng? focusLatLng; final double zoomDelta = json[1] as double? ?? 0; // Web only supports integer changes... - final int newZoomDelta = zoomDelta < 0 ? zoomDelta.floor() : zoomDelta.ceil(); + final int newZoomDelta = + zoomDelta < 0 ? zoomDelta.floor() : zoomDelta.ceil(); if (json.length == 3) { // With focus try { - focusLatLng = _pixelToLatLng(map, json[2][0] as int, json[2][1] as int); + focusLatLng = + _pixelToLatLng(map, json[2][0] as int, json[2][1] as int); } catch (e) { // https://github.com/a14n/dart-google-maps/issues/87 // print('Error computing new focus LatLng. JS Error: ' + e.toString()); diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index 9c5760ece499..b7e902014281 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -308,8 +308,8 @@ class GoogleMapController { assert(_googleMap != null, 'Cannot get the visible region of a null map.'); final gmaps.LatLngBounds bounds = - await Future.value(_googleMap!.bounds) - ?? _nullGmapsLatLngBounds; + await Future.value(_googleMap!.bounds) ?? + _nullGmapsLatLngBounds; return _gmLatLngBoundsTolatLngBounds(bounds); } @@ -319,7 +319,8 @@ class GoogleMapController { assert(_googleMap != null, 'Cannot get the screen coordinates with a null map.'); - final gmaps.Point point = toScreenLocation(_googleMap!, _latLngToGmLatLng(latLng)); + final gmaps.Point point = + toScreenLocation(_googleMap!, _latLngToGmLatLng(latLng)); return ScreenCoordinate(x: point.x!.toInt(), y: point.y!.toInt()); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart index 9845ee03aa25..043952d176a0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart @@ -323,7 +323,10 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { _mapById[creationId] = mapController; - mapController.events.whereType().first.then((WebMapReadyEvent event) { + mapController.events + .whereType() + .first + .then((WebMapReadyEvent event) { assert(creationId == event.mapId, 'Received WebMapReadyEvent for the wrong map'); // Notify the plugin now that there's a fully initialized controller. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart index 909d3d276287..73f229dad181 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart @@ -34,14 +34,16 @@ class MarkersController extends GeometryController { return; } - final gmaps.InfoWindowOptions? infoWindowOptions = _infoWindowOptionsFromMarker(marker); + final gmaps.InfoWindowOptions? infoWindowOptions = + _infoWindowOptionsFromMarker(marker); gmaps.InfoWindow? gmInfoWindow; if (infoWindowOptions != null) { gmInfoWindow = gmaps.InfoWindow(infoWindowOptions); // Google Maps' JS SDK does not have a click event on the InfoWindow, so // we make one... - if (infoWindowOptions.content != null && infoWindowOptions.content is HtmlElement) { + if (infoWindowOptions.content != null && + infoWindowOptions.content is HtmlElement) { final HtmlElement content = infoWindowOptions.content! as HtmlElement; content.onClick.listen((_) { _onInfoWindowTap(marker.markerId); @@ -49,11 +51,12 @@ class MarkersController extends GeometryController { } } - final gmaps.Marker? currentMarker = _markerIdToController[marker.markerId]?.marker; + final gmaps.Marker? currentMarker = + _markerIdToController[marker.markerId]?.marker; - final gmaps.MarkerOptions markerOptions = _markerOptionsFromMarker(marker, currentMarker); - final gmaps.Marker gmMarker = gmaps.Marker(markerOptions) - ..map = googleMap; + final gmaps.MarkerOptions markerOptions = + _markerOptionsFromMarker(marker, currentMarker); + final gmaps.Marker gmMarker = gmaps.Marker(markerOptions)..map = googleMap; final MarkerController controller = MarkerController( marker: gmMarker, infoWindow: gmInfoWindow, @@ -81,13 +84,15 @@ class MarkersController extends GeometryController { } void _changeMarker(Marker marker) { - final MarkerController? markerController = _markerIdToController[marker.markerId]; + final MarkerController? markerController = + _markerIdToController[marker.markerId]; if (markerController != null) { final gmaps.MarkerOptions markerOptions = _markerOptionsFromMarker( marker, markerController.marker, ); - final gmaps.InfoWindowOptions? infoWindow = _infoWindowOptionsFromMarker(marker); + final gmaps.InfoWindowOptions? infoWindow = + _infoWindowOptionsFromMarker(marker); markerController.update( markerOptions, newInfoWindowContent: infoWindow?.content as HtmlElement?, diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart index 4ba17e2aef83..12e378cfc59c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polygons.dart @@ -36,9 +36,10 @@ class PolygonsController extends GeometryController { return; } - final gmaps.PolygonOptions polygonOptions = _polygonOptionsFromPolygon(googleMap, polygon); + final gmaps.PolygonOptions polygonOptions = + _polygonOptionsFromPolygon(googleMap, polygon); final gmaps.Polygon gmPolygon = gmaps.Polygon(polygonOptions) - ..map = googleMap; + ..map = googleMap; final PolygonController controller = PolygonController( polygon: gmPolygon, consumeTapEvents: polygon.consumeTapEvents, @@ -68,7 +69,8 @@ class PolygonsController extends GeometryController { // Removes a polygon and its controller by its [PolygonId]. void _removePolygon(PolygonId polygonId) { - final PolygonController? polygonController = _polygonIdToController[polygonId]; + final PolygonController? polygonController = + _polygonIdToController[polygonId]; polygonController?.remove(); _polygonIdToController.remove(polygonId); } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart index d5333c8d18a3..2d3f1618b42c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/polylines.dart @@ -34,9 +34,10 @@ class PolylinesController extends GeometryController { return; } - final gmaps.PolylineOptions polylineOptions = _polylineOptionsFromPolyline(googleMap, polyline); + final gmaps.PolylineOptions polylineOptions = + _polylineOptionsFromPolyline(googleMap, polyline); final gmaps.Polyline gmPolyline = gmaps.Polyline(polylineOptions) - ..map = googleMap; + ..map = googleMap; final PolylineController controller = PolylineController( polyline: gmPolyline, consumeTapEvents: polyline.consumeTapEvents, @@ -65,7 +66,8 @@ class PolylinesController extends GeometryController { // Removes a polyline and its controller by its [PolylineId]. void _removePolyline(PolylineId polylineId) { - final PolylineController? polylineController = _polylineIdToController[polylineId]; + final PolylineController? polylineController = + _polylineIdToController[polylineId]; polylineController?.remove(); _polylineIdToController.remove(polylineId); } From 73d0682ae521ddfd6d915ea88c67022fbb781aea Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 18 May 2022 18:17:40 -0700 Subject: [PATCH 16/18] Enable regular analysis CI in google_maps_flutter_web --- script/configs/custom_analysis.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/script/configs/custom_analysis.yaml b/script/configs/custom_analysis.yaml index 23b7f7bbc35b..bcd7d37dea0a 100644 --- a/script/configs/custom_analysis.yaml +++ b/script/configs/custom_analysis.yaml @@ -12,4 +12,3 @@ # TODO(ecosystem): Remove everything from this list. See: # https://github.com/flutter/flutter/issues/76229 - google_maps_flutter/google_maps_flutter_platform_interface -- google_maps_flutter/google_maps_flutter_web From 98139c6d752adba39df48daa337489cbb64a82b2 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 18 May 2022 18:55:05 -0700 Subject: [PATCH 17/18] List other changes in the changelog. --- .../google_maps_flutter/google_maps_flutter_web/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index f33703d83a86..8bd3d40babbc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,6 +1,10 @@ ## 0.3.3 * Removes custom `analysis_options.yaml` (and fixes code to comply with newest rules). +* Updates `package:google_maps` dependency to latest (`^6.1.0`). +* Ensures that `convert.dart` sanitizes user-created HTML before passing it to the + Maps JS SDK with `sanitizeHtml` from `package:sanitize_html`. + [More info](https://pub.dev/documentation/sanitize_html/latest/sanitize_html/sanitizeHtml.html). ## 0.3.2+2 From e91cb5b03454df0196e60e659e33c772d736f3ad Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Thu, 19 May 2022 14:54:17 -0700 Subject: [PATCH 18/18] Address PR comments. --- .../lib/src/convert.dart | 18 ++++++++---------- .../lib/src/markers.dart | 4 +++- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 7dd5395f0c94..c6f3164ff207 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -298,10 +298,9 @@ gmaps.CircleOptions _circleOptionsFromCircle(Circle circle) { gmaps.PolygonOptions _polygonOptionsFromPolygon( gmaps.GMap googleMap, Polygon polygon) { - final List path = []; - - // Convert all points to GmLatLng, then add them to the path - polygon.points.map(_latLngToGmLatLng).forEach(path.add); + // Convert all points to GmLatLng + final List path = + polygon.points.map(_latLngToGmLatLng).toList(); final bool isClockwisePolygon = _isPolygonClockwise(path); @@ -333,8 +332,8 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon( List _ensureHoleHasReverseWinding( List hole, bool polyIsClockwise, { - int? holeId, - PolygonId? polygonId, + required int holeId, + required PolygonId polygonId, }) { List holePath = hole.map(_latLngToGmLatLng).toList(); final bool holeIsClockwise = _isPolygonClockwise(holePath); @@ -342,7 +341,7 @@ List _ensureHoleHasReverseWinding( if (holeIsClockwise == polyIsClockwise) { holePath = holePath.reversed.toList(); if (kDebugMode) { - print('Hole [$holeId] in Polygon [${polygonId?.value}] has been reversed.' + print('Hole [$holeId] in Polygon [${polygonId.value}] has been reversed.' ' Ensure holes in polygons are "wound in the opposite direction to the outer path."' ' More info: https://github.com/flutter/flutter/issues/74096'); } @@ -374,9 +373,8 @@ bool _isPolygonClockwise(List path) { gmaps.PolylineOptions _polylineOptionsFromPolyline( gmaps.GMap googleMap, Polyline polyline) { - final List paths = []; - - polyline.points.map(_latLngToGmLatLng).forEach(paths.add); + final List paths = + polyline.points.map(_latLngToGmLatLng).toList(); return gmaps.PolylineOptions() ..path = paths diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart index 73f229dad181..1a712b109677 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/markers.dart @@ -179,6 +179,8 @@ class MarkersController extends GeometryController { _markerIdToController.values .where((MarkerController? controller) => controller?.infoWindowShown ?? false) - .forEach((MarkerController controller) => controller.hideInfoWindow()); + .forEach((MarkerController controller) { + controller.hideInfoWindow(); + }); } }