mirror of
https://github.com/flutter/packages.git
synced 2025-06-28 22:02:38 +08:00
[google_map_flutter] Fix map object regression due to async changes (#4171)
In #4067 I changed several implicitly unawaited futures to `await`, not noticing that doing so would change the timing on updating fields that were used to compute diffs for future updates. Since the update flow is unawaited at higher levels, this meant that multiple calls to update map objects in rapid succession would compute incorrect diffs due to using the wrong base objects. This fixes that by restoring the old flow using `unawaited`. Adds new tests that introduce synthetic awaits into the fake platform interface object and perform multiple updates in a row that should have different base object sets, which fail without the fix. In order to simplify adding that behavior to the fake, and to pay down technical debt in the unit tests, I replaced the old test fake that is based on method channel interception (which predates the federation of the plugin and is implicitly relying on the method channel implementation from a different package never changing) with a fake platform interface implementation (substantially simplifying the fake). Fixes https://github.com/flutter/flutter/issues/128042
This commit is contained in:
@ -1,5 +1,7 @@
|
||||
## NEXT
|
||||
## 2.3.1
|
||||
|
||||
* Fixes a regression from 2.2.8 that could cause incorrect handling of a
|
||||
rapid series of map object updates.
|
||||
* Fixes stale ignore: prefer_const_constructors.
|
||||
* Updates minimum supported SDK version to Flutter 3.10/Dart 3.0.
|
||||
|
||||
|
@ -360,41 +360,41 @@ class _GoogleMapState extends State<GoogleMap> {
|
||||
return;
|
||||
}
|
||||
final GoogleMapController controller = await _controller.future;
|
||||
await controller._updateMapConfiguration(updates);
|
||||
unawaited(controller._updateMapConfiguration(updates));
|
||||
_mapConfiguration = newConfig;
|
||||
}
|
||||
|
||||
Future<void> _updateMarkers() async {
|
||||
final GoogleMapController controller = await _controller.future;
|
||||
await controller._updateMarkers(
|
||||
MarkerUpdates.from(_markers.values.toSet(), widget.markers));
|
||||
unawaited(controller._updateMarkers(
|
||||
MarkerUpdates.from(_markers.values.toSet(), widget.markers)));
|
||||
_markers = keyByMarkerId(widget.markers);
|
||||
}
|
||||
|
||||
Future<void> _updatePolygons() async {
|
||||
final GoogleMapController controller = await _controller.future;
|
||||
await controller._updatePolygons(
|
||||
PolygonUpdates.from(_polygons.values.toSet(), widget.polygons));
|
||||
unawaited(controller._updatePolygons(
|
||||
PolygonUpdates.from(_polygons.values.toSet(), widget.polygons)));
|
||||
_polygons = keyByPolygonId(widget.polygons);
|
||||
}
|
||||
|
||||
Future<void> _updatePolylines() async {
|
||||
final GoogleMapController controller = await _controller.future;
|
||||
await controller._updatePolylines(
|
||||
PolylineUpdates.from(_polylines.values.toSet(), widget.polylines));
|
||||
unawaited(controller._updatePolylines(
|
||||
PolylineUpdates.from(_polylines.values.toSet(), widget.polylines)));
|
||||
_polylines = keyByPolylineId(widget.polylines);
|
||||
}
|
||||
|
||||
Future<void> _updateCircles() async {
|
||||
final GoogleMapController controller = await _controller.future;
|
||||
await controller._updateCircles(
|
||||
CircleUpdates.from(_circles.values.toSet(), widget.circles));
|
||||
unawaited(controller._updateCircles(
|
||||
CircleUpdates.from(_circles.values.toSet(), widget.circles)));
|
||||
_circles = keyByCircleId(widget.circles);
|
||||
}
|
||||
|
||||
Future<void> _updateTileOverlays() async {
|
||||
final GoogleMapController controller = await _controller.future;
|
||||
await controller._updateTileOverlays(widget.tileOverlays);
|
||||
unawaited(controller._updateTileOverlays(widget.tileOverlays));
|
||||
}
|
||||
|
||||
Future<void> onPlatformViewCreated(int id) async {
|
||||
|
@ -2,7 +2,7 @@ name: google_maps_flutter
|
||||
description: A Flutter plugin for integrating Google Maps in iOS and Android applications.
|
||||
repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter
|
||||
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
|
||||
version: 2.3.0
|
||||
version: 2.3.1
|
||||
|
||||
environment:
|
||||
sdk: ">=3.0.0 <4.0.0"
|
||||
|
@ -2,12 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
|
||||
|
||||
import 'fake_maps_controllers.dart';
|
||||
import 'fake_google_maps_flutter_platform.dart';
|
||||
|
||||
Widget _mapWithCircles(Set<Circle> circles) {
|
||||
return Directionality(
|
||||
@ -20,36 +20,24 @@ Widget _mapWithCircles(Set<Circle> circles) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final FakePlatformViewsController fakePlatformViewsController =
|
||||
FakePlatformViewsController();
|
||||
|
||||
setUpAll(() {
|
||||
_ambiguate(TestDefaultBinaryMessengerBinding.instance)!
|
||||
.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(
|
||||
SystemChannels.platform_views,
|
||||
fakePlatformViewsController.fakePlatformViewsMethodHandler,
|
||||
);
|
||||
});
|
||||
late FakeGoogleMapsFlutterPlatform platform;
|
||||
|
||||
setUp(() {
|
||||
fakePlatformViewsController.reset();
|
||||
platform = FakeGoogleMapsFlutterPlatform();
|
||||
GoogleMapsFlutterPlatform.instance = platform;
|
||||
});
|
||||
|
||||
testWidgets('Initializing a circle', (WidgetTester tester) async {
|
||||
const Circle c1 = Circle(circleId: CircleId('circle_1'));
|
||||
await tester.pumpWidget(_mapWithCircles(<Circle>{c1}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.circlesToAdd.length, 1);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.circleUpdates.last.circlesToAdd.length, 1);
|
||||
|
||||
final Circle initializedCircle = platformGoogleMap.circlesToAdd.first;
|
||||
final Circle initializedCircle = map.circleUpdates.last.circlesToAdd.first;
|
||||
expect(initializedCircle, equals(c1));
|
||||
expect(platformGoogleMap.circleIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.circlesToChange.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circleIdsToRemove.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circlesToChange.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Adding a circle', (WidgetTester tester) async {
|
||||
@ -59,16 +47,15 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithCircles(<Circle>{c1}));
|
||||
await tester.pumpWidget(_mapWithCircles(<Circle>{c1, c2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.circlesToAdd.length, 1);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.circleUpdates.last.circlesToAdd.length, 1);
|
||||
|
||||
final Circle addedCircle = platformGoogleMap.circlesToAdd.first;
|
||||
final Circle addedCircle = map.circleUpdates.last.circlesToAdd.first;
|
||||
expect(addedCircle, equals(c2));
|
||||
|
||||
expect(platformGoogleMap.circleIdsToRemove.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circleIdsToRemove.isEmpty, true);
|
||||
|
||||
expect(platformGoogleMap.circlesToChange.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circlesToChange.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Removing a circle', (WidgetTester tester) async {
|
||||
@ -77,13 +64,12 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithCircles(<Circle>{c1}));
|
||||
await tester.pumpWidget(_mapWithCircles(<Circle>{}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.circleIdsToRemove.length, 1);
|
||||
expect(platformGoogleMap.circleIdsToRemove.first, equals(c1.circleId));
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.circleUpdates.last.circleIdsToRemove.length, 1);
|
||||
expect(map.circleUpdates.last.circleIdsToRemove.first, equals(c1.circleId));
|
||||
|
||||
expect(platformGoogleMap.circlesToChange.isEmpty, true);
|
||||
expect(platformGoogleMap.circlesToAdd.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circlesToChange.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circlesToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Updating a circle', (WidgetTester tester) async {
|
||||
@ -93,13 +79,12 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithCircles(<Circle>{c1}));
|
||||
await tester.pumpWidget(_mapWithCircles(<Circle>{c2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.circlesToChange.length, 1);
|
||||
expect(platformGoogleMap.circlesToChange.first, equals(c2));
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.circleUpdates.last.circlesToChange.length, 1);
|
||||
expect(map.circleUpdates.last.circlesToChange.first, equals(c2));
|
||||
|
||||
expect(platformGoogleMap.circleIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.circlesToAdd.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circleIdsToRemove.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circlesToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Updating a circle', (WidgetTester tester) async {
|
||||
@ -109,11 +94,10 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithCircles(<Circle>{c1}));
|
||||
await tester.pumpWidget(_mapWithCircles(<Circle>{c2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.circlesToChange.length, 1);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.circleUpdates.last.circlesToChange.length, 1);
|
||||
|
||||
final Circle update = platformGoogleMap.circlesToChange.first;
|
||||
final Circle update = map.circleUpdates.last.circlesToChange.first;
|
||||
expect(update, equals(c2));
|
||||
expect(update.radius, 10);
|
||||
});
|
||||
@ -129,12 +113,11 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithCircles(prev));
|
||||
await tester.pumpWidget(_mapWithCircles(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.circlesToChange, cur);
|
||||
expect(platformGoogleMap.circleIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.circlesToAdd.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circlesToChange, cur);
|
||||
expect(map.circleUpdates.last.circleIdsToRemove.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circlesToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Multi Update', (WidgetTester tester) async {
|
||||
@ -150,16 +133,15 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithCircles(prev));
|
||||
await tester.pumpWidget(_mapWithCircles(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.circlesToChange.length, 1);
|
||||
expect(platformGoogleMap.circlesToAdd.length, 1);
|
||||
expect(platformGoogleMap.circleIdsToRemove.length, 1);
|
||||
expect(map.circleUpdates.last.circlesToChange.length, 1);
|
||||
expect(map.circleUpdates.last.circlesToAdd.length, 1);
|
||||
expect(map.circleUpdates.last.circleIdsToRemove.length, 1);
|
||||
|
||||
expect(platformGoogleMap.circlesToChange.first, equals(c2));
|
||||
expect(platformGoogleMap.circlesToAdd.first, equals(c1));
|
||||
expect(platformGoogleMap.circleIdsToRemove.first, equals(c3.circleId));
|
||||
expect(map.circleUpdates.last.circlesToChange.first, equals(c2));
|
||||
expect(map.circleUpdates.last.circlesToAdd.first, equals(c1));
|
||||
expect(map.circleUpdates.last.circleIdsToRemove.first, equals(c3.circleId));
|
||||
});
|
||||
|
||||
testWidgets('Partial Update', (WidgetTester tester) async {
|
||||
@ -173,12 +155,11 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithCircles(prev));
|
||||
await tester.pumpWidget(_mapWithCircles(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.circlesToChange, <Circle>{c3});
|
||||
expect(platformGoogleMap.circleIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.circlesToAdd.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circlesToChange, <Circle>{c3});
|
||||
expect(map.circleUpdates.last.circleIdsToRemove.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circlesToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Update non platform related attr', (WidgetTester tester) async {
|
||||
@ -190,17 +171,42 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithCircles(prev));
|
||||
await tester.pumpWidget(_mapWithCircles(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.circlesToChange.isEmpty, true);
|
||||
expect(platformGoogleMap.circleIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.circlesToAdd.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circlesToChange.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circleIdsToRemove.isEmpty, true);
|
||||
expect(map.circleUpdates.last.circlesToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('multi-update with delays', (WidgetTester tester) async {
|
||||
platform.simulatePlatformDelay = true;
|
||||
|
||||
const Circle c1 = Circle(circleId: CircleId('circle_1'));
|
||||
const Circle c2 = Circle(circleId: CircleId('circle_2'));
|
||||
const Circle c3 = Circle(circleId: CircleId('circle_3'), radius: 1);
|
||||
const Circle c3updated = Circle(circleId: CircleId('circle_3'), radius: 10);
|
||||
|
||||
// First remove one and add another, then update the new one.
|
||||
await tester.pumpWidget(_mapWithCircles(<Circle>{c1, c2}));
|
||||
await tester.pumpWidget(_mapWithCircles(<Circle>{c1, c3}));
|
||||
await tester.pumpWidget(_mapWithCircles(<Circle>{c1, c3updated}));
|
||||
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(map.circleUpdates.length, 3);
|
||||
|
||||
expect(map.circleUpdates[0].circlesToChange.isEmpty, true);
|
||||
expect(map.circleUpdates[0].circlesToAdd, <Circle>{c1, c2});
|
||||
expect(map.circleUpdates[0].circleIdsToRemove.isEmpty, true);
|
||||
|
||||
expect(map.circleUpdates[1].circlesToChange.isEmpty, true);
|
||||
expect(map.circleUpdates[1].circlesToAdd, <Circle>{c3});
|
||||
expect(map.circleUpdates[1].circleIdsToRemove, <CircleId>{c2.circleId});
|
||||
|
||||
expect(map.circleUpdates[2].circlesToChange, <Circle>{c3updated});
|
||||
expect(map.circleUpdates[2].circlesToAdd.isEmpty, true);
|
||||
expect(map.circleUpdates[2].circleIdsToRemove.isEmpty, true);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
}
|
||||
|
||||
/// This allows a value of type T or T? to be treated as a value of type T?.
|
||||
///
|
||||
/// We use this so that APIs that have become non-nullable can still be used
|
||||
/// with `!` and `?` on the stable branch.
|
||||
T? _ambiguate<T>(T? value) => value;
|
||||
|
@ -0,0 +1,303 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
|
||||
import 'package:stream_transform/stream_transform.dart';
|
||||
|
||||
// A dummy implementation of the platform interface for tests.
|
||||
class FakeGoogleMapsFlutterPlatform extends GoogleMapsFlutterPlatform {
|
||||
FakeGoogleMapsFlutterPlatform();
|
||||
|
||||
/// The IDs passed to each call to buildView, in call order.
|
||||
List<int> createdIds = <int>[];
|
||||
|
||||
/// A map of creation IDs to fake map instances.
|
||||
Map<int, PlatformMapStateRecorder> mapInstances =
|
||||
<int, PlatformMapStateRecorder>{};
|
||||
|
||||
PlatformMapStateRecorder get lastCreatedMap => mapInstances[createdIds.last]!;
|
||||
|
||||
/// Whether to add a small delay to async calls to simulate more realistic
|
||||
/// async behavior (simulating the platform channel calls most
|
||||
/// implementations will do).
|
||||
///
|
||||
/// When true, requires tests to `pumpAndSettle` at the end of the test
|
||||
/// to avoid exceptions.
|
||||
bool simulatePlatformDelay = false;
|
||||
|
||||
/// Whether `dispose` has been called.
|
||||
bool disposed = false;
|
||||
|
||||
/// Stream controller to inject events for testing.
|
||||
final StreamController<MapEvent<dynamic>> mapEventStreamController =
|
||||
StreamController<MapEvent<dynamic>>.broadcast();
|
||||
|
||||
@override
|
||||
Future<void> init(int mapId) async {}
|
||||
|
||||
@override
|
||||
Future<void> updateMapConfiguration(
|
||||
MapConfiguration update, {
|
||||
required int mapId,
|
||||
}) async {
|
||||
mapInstances[mapId]?.mapConfiguration = update;
|
||||
await _fakeDelay();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateMarkers(
|
||||
MarkerUpdates markerUpdates, {
|
||||
required int mapId,
|
||||
}) async {
|
||||
mapInstances[mapId]?.markerUpdates.add(markerUpdates);
|
||||
await _fakeDelay();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updatePolygons(
|
||||
PolygonUpdates polygonUpdates, {
|
||||
required int mapId,
|
||||
}) async {
|
||||
mapInstances[mapId]?.polygonUpdates.add(polygonUpdates);
|
||||
await _fakeDelay();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updatePolylines(
|
||||
PolylineUpdates polylineUpdates, {
|
||||
required int mapId,
|
||||
}) async {
|
||||
mapInstances[mapId]?.polylineUpdates.add(polylineUpdates);
|
||||
await _fakeDelay();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateCircles(
|
||||
CircleUpdates circleUpdates, {
|
||||
required int mapId,
|
||||
}) async {
|
||||
mapInstances[mapId]?.circleUpdates.add(circleUpdates);
|
||||
await _fakeDelay();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateTileOverlays({
|
||||
required Set<TileOverlay> newTileOverlays,
|
||||
required int mapId,
|
||||
}) async {
|
||||
mapInstances[mapId]?.tileOverlaySets.add(newTileOverlays);
|
||||
await _fakeDelay();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> clearTileCache(
|
||||
TileOverlayId tileOverlayId, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> animateCamera(
|
||||
CameraUpdate cameraUpdate, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> moveCamera(
|
||||
CameraUpdate cameraUpdate, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> setMapStyle(
|
||||
String? mapStyle, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<LatLngBounds> getVisibleRegion({
|
||||
required int mapId,
|
||||
}) async {
|
||||
return LatLngBounds(
|
||||
southwest: const LatLng(0, 0), northeast: const LatLng(0, 0));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ScreenCoordinate> getScreenCoordinate(
|
||||
LatLng latLng, {
|
||||
required int mapId,
|
||||
}) async {
|
||||
return const ScreenCoordinate(x: 0, y: 0);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LatLng> getLatLng(
|
||||
ScreenCoordinate screenCoordinate, {
|
||||
required int mapId,
|
||||
}) async {
|
||||
return const LatLng(0, 0);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> showMarkerInfoWindow(
|
||||
MarkerId markerId, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> hideMarkerInfoWindow(
|
||||
MarkerId markerId, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<bool> isMarkerInfoWindowShown(
|
||||
MarkerId markerId, {
|
||||
required int mapId,
|
||||
}) async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<double> getZoomLevel({
|
||||
required int mapId,
|
||||
}) async {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List?> takeSnapshot({
|
||||
required int mapId,
|
||||
}) async {
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<CameraMoveStartedEvent> onCameraMoveStarted({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<CameraMoveStartedEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<CameraMoveEvent> onCameraMove({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<CameraMoveEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<CameraIdleEvent> onCameraIdle({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<CameraIdleEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<MarkerTapEvent> onMarkerTap({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<MarkerTapEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<InfoWindowTapEvent> onInfoWindowTap({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<InfoWindowTapEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<MarkerDragStartEvent> onMarkerDragStart({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<MarkerDragStartEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<MarkerDragEvent> onMarkerDrag({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<MarkerDragEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<MarkerDragEndEvent> onMarkerDragEnd({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<MarkerDragEndEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<PolylineTapEvent> onPolylineTap({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<PolylineTapEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<PolygonTapEvent> onPolygonTap({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<PolygonTapEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<CircleTapEvent> onCircleTap({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<CircleTapEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<MapTapEvent> onTap({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<MapTapEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<MapLongPressEvent> onLongPress({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<MapLongPressEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose({required int mapId}) {
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildViewWithConfiguration(
|
||||
int creationId,
|
||||
PlatformViewCreatedCallback onPlatformViewCreated, {
|
||||
required MapWidgetConfiguration widgetConfiguration,
|
||||
MapObjects mapObjects = const MapObjects(),
|
||||
MapConfiguration mapConfiguration = const MapConfiguration(),
|
||||
}) {
|
||||
final PlatformMapStateRecorder? instance = mapInstances[creationId];
|
||||
if (instance == null) {
|
||||
createdIds.add(creationId);
|
||||
mapInstances[creationId] = PlatformMapStateRecorder(
|
||||
widgetConfiguration: widgetConfiguration,
|
||||
mapConfiguration: mapConfiguration,
|
||||
mapObjects: mapObjects);
|
||||
onPlatformViewCreated(creationId);
|
||||
}
|
||||
return Container();
|
||||
}
|
||||
|
||||
Future<void> _fakeDelay() async {
|
||||
if (!simulatePlatformDelay) {
|
||||
return;
|
||||
}
|
||||
return Future<void>.delayed(const Duration(microseconds: 1));
|
||||
}
|
||||
}
|
||||
|
||||
/// A fake implementation of a native map, which stores all the updates it is
|
||||
/// sent for inspection in tests.
|
||||
class PlatformMapStateRecorder {
|
||||
PlatformMapStateRecorder({
|
||||
required this.widgetConfiguration,
|
||||
this.mapObjects = const MapObjects(),
|
||||
this.mapConfiguration = const MapConfiguration(),
|
||||
}) {
|
||||
markerUpdates.add(MarkerUpdates.from(const <Marker>{}, mapObjects.markers));
|
||||
polygonUpdates
|
||||
.add(PolygonUpdates.from(const <Polygon>{}, mapObjects.polygons));
|
||||
polylineUpdates
|
||||
.add(PolylineUpdates.from(const <Polyline>{}, mapObjects.polylines));
|
||||
circleUpdates.add(CircleUpdates.from(const <Circle>{}, mapObjects.circles));
|
||||
tileOverlaySets.add(mapObjects.tileOverlays);
|
||||
}
|
||||
|
||||
MapWidgetConfiguration widgetConfiguration;
|
||||
MapObjects mapObjects;
|
||||
MapConfiguration mapConfiguration;
|
||||
|
||||
final List<MarkerUpdates> markerUpdates = <MarkerUpdates>[];
|
||||
final List<PolygonUpdates> polygonUpdates = <PolygonUpdates>[];
|
||||
final List<PolylineUpdates> polylineUpdates = <PolylineUpdates>[];
|
||||
final List<CircleUpdates> circleUpdates = <CircleUpdates>[];
|
||||
final List<Set<TileOverlay>> tileOverlaySets = <Set<TileOverlay>>[];
|
||||
}
|
@ -1,485 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
|
||||
class FakePlatformGoogleMap {
|
||||
FakePlatformGoogleMap(int id, Map<dynamic, dynamic> params)
|
||||
: cameraPosition =
|
||||
CameraPosition.fromMap(params['initialCameraPosition']),
|
||||
channel = MethodChannel('plugins.flutter.io/google_maps_$id') {
|
||||
_ambiguate(TestDefaultBinaryMessengerBinding.instance)!
|
||||
.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(channel, onMethodCall);
|
||||
updateOptions(params['options'] as Map<dynamic, dynamic>);
|
||||
updateMarkers(params);
|
||||
updatePolygons(params);
|
||||
updatePolylines(params);
|
||||
updateCircles(params);
|
||||
updateTileOverlays(Map.castFrom<dynamic, dynamic, String, dynamic>(params));
|
||||
}
|
||||
|
||||
MethodChannel channel;
|
||||
|
||||
CameraPosition? cameraPosition;
|
||||
|
||||
bool? compassEnabled;
|
||||
|
||||
bool? mapToolbarEnabled;
|
||||
|
||||
CameraTargetBounds? cameraTargetBounds;
|
||||
|
||||
MapType? mapType;
|
||||
|
||||
MinMaxZoomPreference? minMaxZoomPreference;
|
||||
|
||||
bool? rotateGesturesEnabled;
|
||||
|
||||
bool? scrollGesturesEnabled;
|
||||
|
||||
bool? tiltGesturesEnabled;
|
||||
|
||||
bool? zoomGesturesEnabled;
|
||||
|
||||
bool? zoomControlsEnabled;
|
||||
|
||||
bool? liteModeEnabled;
|
||||
|
||||
bool? trackCameraPosition;
|
||||
|
||||
bool? myLocationEnabled;
|
||||
|
||||
bool? trafficEnabled;
|
||||
|
||||
bool? buildingsEnabled;
|
||||
|
||||
bool? myLocationButtonEnabled;
|
||||
|
||||
List<dynamic>? padding;
|
||||
|
||||
Set<MarkerId> markerIdsToRemove = <MarkerId>{};
|
||||
|
||||
Set<Marker> markersToAdd = <Marker>{};
|
||||
|
||||
Set<Marker> markersToChange = <Marker>{};
|
||||
|
||||
Set<PolygonId> polygonIdsToRemove = <PolygonId>{};
|
||||
|
||||
Set<Polygon> polygonsToAdd = <Polygon>{};
|
||||
|
||||
Set<Polygon> polygonsToChange = <Polygon>{};
|
||||
|
||||
Set<PolylineId> polylineIdsToRemove = <PolylineId>{};
|
||||
|
||||
Set<Polyline> polylinesToAdd = <Polyline>{};
|
||||
|
||||
Set<Polyline> polylinesToChange = <Polyline>{};
|
||||
|
||||
Set<CircleId> circleIdsToRemove = <CircleId>{};
|
||||
|
||||
Set<Circle> circlesToAdd = <Circle>{};
|
||||
|
||||
Set<Circle> circlesToChange = <Circle>{};
|
||||
|
||||
Set<TileOverlayId> tileOverlayIdsToRemove = <TileOverlayId>{};
|
||||
|
||||
Set<TileOverlay> tileOverlaysToAdd = <TileOverlay>{};
|
||||
|
||||
Set<TileOverlay> tileOverlaysToChange = <TileOverlay>{};
|
||||
|
||||
Future<dynamic> onMethodCall(MethodCall call) {
|
||||
switch (call.method) {
|
||||
case 'map#update':
|
||||
final Map<String, Object?> arguments =
|
||||
(call.arguments as Map<Object?, Object?>).cast<String, Object?>();
|
||||
updateOptions(arguments['options']! as Map<dynamic, dynamic>);
|
||||
return Future<void>.sync(() {});
|
||||
case 'markers#update':
|
||||
updateMarkers(call.arguments as Map<dynamic, dynamic>?);
|
||||
return Future<void>.sync(() {});
|
||||
case 'polygons#update':
|
||||
updatePolygons(call.arguments as Map<dynamic, dynamic>?);
|
||||
return Future<void>.sync(() {});
|
||||
case 'polylines#update':
|
||||
updatePolylines(call.arguments as Map<dynamic, dynamic>?);
|
||||
return Future<void>.sync(() {});
|
||||
case 'tileOverlays#update':
|
||||
updateTileOverlays(Map.castFrom<dynamic, dynamic, String, dynamic>(
|
||||
call.arguments as Map<dynamic, dynamic>));
|
||||
return Future<void>.sync(() {});
|
||||
case 'circles#update':
|
||||
updateCircles(call.arguments as Map<dynamic, dynamic>?);
|
||||
return Future<void>.sync(() {});
|
||||
default:
|
||||
return Future<void>.sync(() {});
|
||||
}
|
||||
}
|
||||
|
||||
void updateMarkers(Map<dynamic, dynamic>? markerUpdates) {
|
||||
if (markerUpdates == null) {
|
||||
return;
|
||||
}
|
||||
markersToAdd = _deserializeMarkers(markerUpdates['markersToAdd']);
|
||||
markerIdsToRemove = _deserializeMarkerIds(
|
||||
markerUpdates['markerIdsToRemove'] as List<dynamic>?);
|
||||
markersToChange = _deserializeMarkers(markerUpdates['markersToChange']);
|
||||
}
|
||||
|
||||
Set<MarkerId> _deserializeMarkerIds(List<dynamic>? markerIds) {
|
||||
if (markerIds == null) {
|
||||
return <MarkerId>{};
|
||||
}
|
||||
return markerIds
|
||||
.map((dynamic markerId) => MarkerId(markerId as String))
|
||||
.toSet();
|
||||
}
|
||||
|
||||
Set<Marker> _deserializeMarkers(dynamic markers) {
|
||||
if (markers == null) {
|
||||
return <Marker>{};
|
||||
}
|
||||
final List<dynamic> markersData = markers as List<dynamic>;
|
||||
final Set<Marker> result = <Marker>{};
|
||||
for (final Map<dynamic, dynamic> markerData
|
||||
in markersData.cast<Map<dynamic, dynamic>>()) {
|
||||
final String markerId = markerData['markerId'] as String;
|
||||
final double alpha = markerData['alpha'] as double;
|
||||
final bool draggable = markerData['draggable'] as bool;
|
||||
final bool visible = markerData['visible'] as bool;
|
||||
|
||||
final dynamic infoWindowData = markerData['infoWindow'];
|
||||
InfoWindow infoWindow = InfoWindow.noText;
|
||||
if (infoWindowData != null) {
|
||||
final Map<dynamic, dynamic> infoWindowMap =
|
||||
infoWindowData as Map<dynamic, dynamic>;
|
||||
infoWindow = InfoWindow(
|
||||
title: infoWindowMap['title'] as String?,
|
||||
snippet: infoWindowMap['snippet'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
result.add(Marker(
|
||||
markerId: MarkerId(markerId),
|
||||
draggable: draggable,
|
||||
visible: visible,
|
||||
infoWindow: infoWindow,
|
||||
alpha: alpha,
|
||||
));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void updatePolygons(Map<dynamic, dynamic>? polygonUpdates) {
|
||||
if (polygonUpdates == null) {
|
||||
return;
|
||||
}
|
||||
polygonsToAdd = _deserializePolygons(polygonUpdates['polygonsToAdd']);
|
||||
polygonIdsToRemove = _deserializePolygonIds(
|
||||
polygonUpdates['polygonIdsToRemove'] as List<dynamic>?);
|
||||
polygonsToChange = _deserializePolygons(polygonUpdates['polygonsToChange']);
|
||||
}
|
||||
|
||||
Set<PolygonId> _deserializePolygonIds(List<dynamic>? polygonIds) {
|
||||
if (polygonIds == null) {
|
||||
return <PolygonId>{};
|
||||
}
|
||||
return polygonIds
|
||||
.map((dynamic polygonId) => PolygonId(polygonId as String))
|
||||
.toSet();
|
||||
}
|
||||
|
||||
Set<Polygon> _deserializePolygons(dynamic polygons) {
|
||||
if (polygons == null) {
|
||||
return <Polygon>{};
|
||||
}
|
||||
final List<dynamic> polygonsData = polygons as List<dynamic>;
|
||||
final Set<Polygon> result = <Polygon>{};
|
||||
for (final Map<dynamic, dynamic> polygonData
|
||||
in polygonsData.cast<Map<dynamic, dynamic>>()) {
|
||||
final String polygonId = polygonData['polygonId'] as String;
|
||||
final bool visible = polygonData['visible'] as bool;
|
||||
final bool geodesic = polygonData['geodesic'] as bool;
|
||||
final List<LatLng> points =
|
||||
_deserializePoints(polygonData['points'] as List<dynamic>);
|
||||
final List<List<LatLng>> holes =
|
||||
_deserializeHoles(polygonData['holes'] as List<dynamic>);
|
||||
|
||||
result.add(Polygon(
|
||||
polygonId: PolygonId(polygonId),
|
||||
visible: visible,
|
||||
geodesic: geodesic,
|
||||
points: points,
|
||||
holes: holes,
|
||||
));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Converts a list of points expressed as two-element lists of doubles into
|
||||
// a list of `LatLng`s. All list items are assumed to be non-null.
|
||||
List<LatLng> _deserializePoints(List<dynamic> points) {
|
||||
return points.map<LatLng>((dynamic item) {
|
||||
final List<Object?> list = item as List<Object?>;
|
||||
return LatLng(list[0]! as double, list[1]! as double);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
List<List<LatLng>> _deserializeHoles(List<dynamic> holes) {
|
||||
return holes.map<List<LatLng>>((dynamic hole) {
|
||||
return _deserializePoints(hole as List<dynamic>);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
void updatePolylines(Map<dynamic, dynamic>? polylineUpdates) {
|
||||
if (polylineUpdates == null) {
|
||||
return;
|
||||
}
|
||||
polylinesToAdd = _deserializePolylines(polylineUpdates['polylinesToAdd']);
|
||||
polylineIdsToRemove = _deserializePolylineIds(
|
||||
polylineUpdates['polylineIdsToRemove'] as List<dynamic>?);
|
||||
polylinesToChange =
|
||||
_deserializePolylines(polylineUpdates['polylinesToChange']);
|
||||
}
|
||||
|
||||
Set<PolylineId> _deserializePolylineIds(List<dynamic>? polylineIds) {
|
||||
if (polylineIds == null) {
|
||||
return <PolylineId>{};
|
||||
}
|
||||
return polylineIds
|
||||
.map((dynamic polylineId) => PolylineId(polylineId as String))
|
||||
.toSet();
|
||||
}
|
||||
|
||||
Set<Polyline> _deserializePolylines(dynamic polylines) {
|
||||
if (polylines == null) {
|
||||
return <Polyline>{};
|
||||
}
|
||||
final List<dynamic> polylinesData = polylines as List<dynamic>;
|
||||
final Set<Polyline> result = <Polyline>{};
|
||||
for (final Map<dynamic, dynamic> polylineData
|
||||
in polylinesData.cast<Map<dynamic, dynamic>>()) {
|
||||
final String polylineId = polylineData['polylineId'] as String;
|
||||
final bool visible = polylineData['visible'] as bool;
|
||||
final bool geodesic = polylineData['geodesic'] as bool;
|
||||
final List<LatLng> points =
|
||||
_deserializePoints(polylineData['points'] as List<dynamic>);
|
||||
|
||||
result.add(Polyline(
|
||||
polylineId: PolylineId(polylineId),
|
||||
visible: visible,
|
||||
geodesic: geodesic,
|
||||
points: points,
|
||||
));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void updateCircles(Map<dynamic, dynamic>? circleUpdates) {
|
||||
if (circleUpdates == null) {
|
||||
return;
|
||||
}
|
||||
circlesToAdd = _deserializeCircles(circleUpdates['circlesToAdd']);
|
||||
circleIdsToRemove = _deserializeCircleIds(
|
||||
circleUpdates['circleIdsToRemove'] as List<dynamic>?);
|
||||
circlesToChange = _deserializeCircles(circleUpdates['circlesToChange']);
|
||||
}
|
||||
|
||||
void updateTileOverlays(Map<String, dynamic> updateTileOverlayUpdates) {
|
||||
final List<Map<dynamic, dynamic>>? tileOverlaysToAddList =
|
||||
updateTileOverlayUpdates['tileOverlaysToAdd'] != null
|
||||
? List.castFrom<dynamic, Map<dynamic, dynamic>>(
|
||||
updateTileOverlayUpdates['tileOverlaysToAdd'] as List<dynamic>)
|
||||
: null;
|
||||
final List<String>? tileOverlayIdsToRemoveList =
|
||||
updateTileOverlayUpdates['tileOverlayIdsToRemove'] != null
|
||||
? List.castFrom<dynamic, String>(
|
||||
updateTileOverlayUpdates['tileOverlayIdsToRemove']
|
||||
as List<dynamic>)
|
||||
: null;
|
||||
final List<Map<dynamic, dynamic>>? tileOverlaysToChangeList =
|
||||
updateTileOverlayUpdates['tileOverlaysToChange'] != null
|
||||
? List.castFrom<dynamic, Map<dynamic, dynamic>>(
|
||||
updateTileOverlayUpdates['tileOverlaysToChange']
|
||||
as List<dynamic>)
|
||||
: null;
|
||||
tileOverlaysToAdd = _deserializeTileOverlays(tileOverlaysToAddList);
|
||||
tileOverlayIdsToRemove =
|
||||
_deserializeTileOverlayIds(tileOverlayIdsToRemoveList);
|
||||
tileOverlaysToChange = _deserializeTileOverlays(tileOverlaysToChangeList);
|
||||
}
|
||||
|
||||
Set<CircleId> _deserializeCircleIds(List<dynamic>? circleIds) {
|
||||
if (circleIds == null) {
|
||||
return <CircleId>{};
|
||||
}
|
||||
return circleIds
|
||||
.map((dynamic circleId) => CircleId(circleId as String))
|
||||
.toSet();
|
||||
}
|
||||
|
||||
Set<Circle> _deserializeCircles(dynamic circles) {
|
||||
if (circles == null) {
|
||||
return <Circle>{};
|
||||
}
|
||||
final List<dynamic> circlesData = circles as List<dynamic>;
|
||||
final Set<Circle> result = <Circle>{};
|
||||
for (final Map<dynamic, dynamic> circleData
|
||||
in circlesData.cast<Map<dynamic, dynamic>>()) {
|
||||
final String circleId = circleData['circleId'] as String;
|
||||
final bool visible = circleData['visible'] as bool;
|
||||
final double radius = circleData['radius'] as double;
|
||||
|
||||
result.add(Circle(
|
||||
circleId: CircleId(circleId),
|
||||
visible: visible,
|
||||
radius: radius,
|
||||
));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Set<TileOverlayId> _deserializeTileOverlayIds(List<String>? tileOverlayIds) {
|
||||
if (tileOverlayIds == null || tileOverlayIds.isEmpty) {
|
||||
return <TileOverlayId>{};
|
||||
}
|
||||
return tileOverlayIds
|
||||
.map((String tileOverlayId) => TileOverlayId(tileOverlayId))
|
||||
.toSet();
|
||||
}
|
||||
|
||||
Set<TileOverlay> _deserializeTileOverlays(
|
||||
List<Map<dynamic, dynamic>>? tileOverlays) {
|
||||
if (tileOverlays == null || tileOverlays.isEmpty) {
|
||||
return <TileOverlay>{};
|
||||
}
|
||||
final Set<TileOverlay> result = <TileOverlay>{};
|
||||
for (final Map<dynamic, dynamic> tileOverlayData in tileOverlays) {
|
||||
final String tileOverlayId = tileOverlayData['tileOverlayId'] as String;
|
||||
final bool fadeIn = tileOverlayData['fadeIn'] as bool;
|
||||
final double transparency = tileOverlayData['transparency'] as double;
|
||||
final int zIndex = tileOverlayData['zIndex'] as int;
|
||||
final bool visible = tileOverlayData['visible'] as bool;
|
||||
|
||||
result.add(TileOverlay(
|
||||
tileOverlayId: TileOverlayId(tileOverlayId),
|
||||
fadeIn: fadeIn,
|
||||
transparency: transparency,
|
||||
zIndex: zIndex,
|
||||
visible: visible,
|
||||
));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void updateOptions(Map<dynamic, dynamic> options) {
|
||||
if (options.containsKey('compassEnabled')) {
|
||||
compassEnabled = options['compassEnabled'] as bool?;
|
||||
}
|
||||
if (options.containsKey('mapToolbarEnabled')) {
|
||||
mapToolbarEnabled = options['mapToolbarEnabled'] as bool?;
|
||||
}
|
||||
if (options.containsKey('cameraTargetBounds')) {
|
||||
final List<dynamic> boundsList =
|
||||
options['cameraTargetBounds'] as List<dynamic>;
|
||||
cameraTargetBounds = boundsList[0] == null
|
||||
? CameraTargetBounds.unbounded
|
||||
: CameraTargetBounds(LatLngBounds.fromList(boundsList[0]));
|
||||
}
|
||||
if (options.containsKey('mapType')) {
|
||||
mapType = MapType.values[options['mapType'] as int];
|
||||
}
|
||||
if (options.containsKey('minMaxZoomPreference')) {
|
||||
final List<dynamic> minMaxZoomList =
|
||||
options['minMaxZoomPreference'] as List<dynamic>;
|
||||
minMaxZoomPreference = MinMaxZoomPreference(
|
||||
minMaxZoomList[0] as double?, minMaxZoomList[1] as double?);
|
||||
}
|
||||
if (options.containsKey('rotateGesturesEnabled')) {
|
||||
rotateGesturesEnabled = options['rotateGesturesEnabled'] as bool?;
|
||||
}
|
||||
if (options.containsKey('scrollGesturesEnabled')) {
|
||||
scrollGesturesEnabled = options['scrollGesturesEnabled'] as bool?;
|
||||
}
|
||||
if (options.containsKey('tiltGesturesEnabled')) {
|
||||
tiltGesturesEnabled = options['tiltGesturesEnabled'] as bool?;
|
||||
}
|
||||
if (options.containsKey('trackCameraPosition')) {
|
||||
trackCameraPosition = options['trackCameraPosition'] as bool?;
|
||||
}
|
||||
if (options.containsKey('zoomGesturesEnabled')) {
|
||||
zoomGesturesEnabled = options['zoomGesturesEnabled'] as bool?;
|
||||
}
|
||||
if (options.containsKey('zoomControlsEnabled')) {
|
||||
zoomControlsEnabled = options['zoomControlsEnabled'] as bool?;
|
||||
}
|
||||
if (options.containsKey('liteModeEnabled')) {
|
||||
liteModeEnabled = options['liteModeEnabled'] as bool?;
|
||||
}
|
||||
if (options.containsKey('myLocationEnabled')) {
|
||||
myLocationEnabled = options['myLocationEnabled'] as bool?;
|
||||
}
|
||||
if (options.containsKey('myLocationButtonEnabled')) {
|
||||
myLocationButtonEnabled = options['myLocationButtonEnabled'] as bool?;
|
||||
}
|
||||
if (options.containsKey('trafficEnabled')) {
|
||||
trafficEnabled = options['trafficEnabled'] as bool?;
|
||||
}
|
||||
if (options.containsKey('buildingsEnabled')) {
|
||||
buildingsEnabled = options['buildingsEnabled'] as bool?;
|
||||
}
|
||||
if (options.containsKey('padding')) {
|
||||
padding = options['padding'] as List<dynamic>?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FakePlatformViewsController {
|
||||
FakePlatformGoogleMap? lastCreatedView;
|
||||
|
||||
Future<dynamic> fakePlatformViewsMethodHandler(MethodCall call) {
|
||||
switch (call.method) {
|
||||
case 'create':
|
||||
final Map<dynamic, dynamic> args =
|
||||
call.arguments as Map<dynamic, dynamic>;
|
||||
final Map<dynamic, dynamic> params =
|
||||
_decodeParams(args['params'] as Uint8List)!;
|
||||
lastCreatedView = FakePlatformGoogleMap(
|
||||
args['id'] as int,
|
||||
params,
|
||||
);
|
||||
return Future<int>.sync(() => 1);
|
||||
default:
|
||||
return Future<void>.sync(() {});
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
lastCreatedView = null;
|
||||
}
|
||||
}
|
||||
|
||||
Map<dynamic, dynamic>? _decodeParams(Uint8List paramsMessage) {
|
||||
final ByteBuffer buffer = paramsMessage.buffer;
|
||||
final ByteData messageBytes = buffer.asByteData(
|
||||
paramsMessage.offsetInBytes,
|
||||
paramsMessage.lengthInBytes,
|
||||
);
|
||||
return const StandardMessageCodec().decodeMessage(messageBytes)
|
||||
as Map<dynamic, dynamic>?;
|
||||
}
|
||||
|
||||
/// This allows a value of type T or T? to be treated as a value of type T?.
|
||||
///
|
||||
/// We use this so that APIs that have become non-nullable can still be used
|
||||
/// with `!` and `?` on the stable branch.
|
||||
T? _ambiguate<T>(T? value) => value;
|
@ -2,30 +2,19 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
|
||||
|
||||
import 'fake_maps_controllers.dart';
|
||||
import 'fake_google_maps_flutter_platform.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final FakePlatformViewsController fakePlatformViewsController =
|
||||
FakePlatformViewsController();
|
||||
|
||||
setUpAll(() {
|
||||
_ambiguate(TestDefaultBinaryMessengerBinding.instance)!
|
||||
.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(
|
||||
SystemChannels.platform_views,
|
||||
fakePlatformViewsController.fakePlatformViewsMethodHandler,
|
||||
);
|
||||
});
|
||||
late FakeGoogleMapsFlutterPlatform platform;
|
||||
|
||||
setUp(() {
|
||||
fakePlatformViewsController.reset();
|
||||
platform = FakeGoogleMapsFlutterPlatform();
|
||||
GoogleMapsFlutterPlatform.instance = platform;
|
||||
});
|
||||
|
||||
testWidgets('Initial camera position', (WidgetTester tester) async {
|
||||
@ -38,10 +27,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.cameraPosition,
|
||||
expect(map.widgetConfiguration.initialCameraPosition,
|
||||
const CameraPosition(target: LatLng(10.0, 15.0)));
|
||||
});
|
||||
|
||||
@ -65,10 +53,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.cameraPosition,
|
||||
expect(map.widgetConfiguration.initialCameraPosition,
|
||||
const CameraPosition(target: LatLng(10.0, 15.0)));
|
||||
});
|
||||
|
||||
@ -83,10 +70,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.compassEnabled, false);
|
||||
expect(map.mapConfiguration.compassEnabled, false);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -97,7 +83,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.compassEnabled, true);
|
||||
expect(map.mapConfiguration.compassEnabled, true);
|
||||
});
|
||||
|
||||
testWidgets('Can update mapToolbarEnabled', (WidgetTester tester) async {
|
||||
@ -111,10 +97,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.mapToolbarEnabled, false);
|
||||
expect(map.mapConfiguration.mapToolbarEnabled, false);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -125,7 +110,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.mapToolbarEnabled, true);
|
||||
expect(map.mapConfiguration.mapToolbarEnabled, true);
|
||||
});
|
||||
|
||||
testWidgets('Can update cameraTargetBounds', (WidgetTester tester) async {
|
||||
@ -145,11 +130,10 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(
|
||||
platformGoogleMap.cameraTargetBounds,
|
||||
map.mapConfiguration.cameraTargetBounds,
|
||||
CameraTargetBounds(
|
||||
LatLngBounds(
|
||||
southwest: const LatLng(10.0, 20.0),
|
||||
@ -174,7 +158,7 @@ void main() {
|
||||
);
|
||||
|
||||
expect(
|
||||
platformGoogleMap.cameraTargetBounds,
|
||||
map.mapConfiguration.cameraTargetBounds,
|
||||
CameraTargetBounds(
|
||||
LatLngBounds(
|
||||
southwest: const LatLng(16.0, 20.0),
|
||||
@ -194,10 +178,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.mapType, MapType.hybrid);
|
||||
expect(map.mapConfiguration.mapType, MapType.hybrid);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -209,7 +192,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.mapType, MapType.satellite);
|
||||
expect(map.mapConfiguration.mapType, MapType.satellite);
|
||||
});
|
||||
|
||||
testWidgets('Can update minMaxZoom', (WidgetTester tester) async {
|
||||
@ -223,10 +206,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.minMaxZoomPreference,
|
||||
expect(map.mapConfiguration.minMaxZoomPreference,
|
||||
const MinMaxZoomPreference(1.0, 3.0));
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -238,8 +220,8 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
platformGoogleMap.minMaxZoomPreference, MinMaxZoomPreference.unbounded);
|
||||
expect(map.mapConfiguration.minMaxZoomPreference,
|
||||
MinMaxZoomPreference.unbounded);
|
||||
});
|
||||
|
||||
testWidgets('Can update rotateGesturesEnabled', (WidgetTester tester) async {
|
||||
@ -253,10 +235,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.rotateGesturesEnabled, false);
|
||||
expect(map.mapConfiguration.rotateGesturesEnabled, false);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -267,7 +248,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.rotateGesturesEnabled, true);
|
||||
expect(map.mapConfiguration.rotateGesturesEnabled, true);
|
||||
});
|
||||
|
||||
testWidgets('Can update scrollGesturesEnabled', (WidgetTester tester) async {
|
||||
@ -281,10 +262,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.scrollGesturesEnabled, false);
|
||||
expect(map.mapConfiguration.scrollGesturesEnabled, false);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -295,7 +275,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.scrollGesturesEnabled, true);
|
||||
expect(map.mapConfiguration.scrollGesturesEnabled, true);
|
||||
});
|
||||
|
||||
testWidgets('Can update tiltGesturesEnabled', (WidgetTester tester) async {
|
||||
@ -309,10 +289,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.tiltGesturesEnabled, false);
|
||||
expect(map.mapConfiguration.tiltGesturesEnabled, false);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -323,7 +302,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.tiltGesturesEnabled, true);
|
||||
expect(map.mapConfiguration.tiltGesturesEnabled, true);
|
||||
});
|
||||
|
||||
testWidgets('Can update trackCameraPosition', (WidgetTester tester) async {
|
||||
@ -336,10 +315,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.trackCameraPosition, false);
|
||||
expect(map.mapConfiguration.trackCameraPosition, false);
|
||||
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -352,7 +330,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.trackCameraPosition, true);
|
||||
expect(map.mapConfiguration.trackCameraPosition, true);
|
||||
});
|
||||
|
||||
testWidgets('Can update zoomGesturesEnabled', (WidgetTester tester) async {
|
||||
@ -366,10 +344,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.zoomGesturesEnabled, false);
|
||||
expect(map.mapConfiguration.zoomGesturesEnabled, false);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -380,7 +357,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.zoomGesturesEnabled, true);
|
||||
expect(map.mapConfiguration.zoomGesturesEnabled, true);
|
||||
});
|
||||
|
||||
testWidgets('Can update zoomControlsEnabled', (WidgetTester tester) async {
|
||||
@ -394,10 +371,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.zoomControlsEnabled, false);
|
||||
expect(map.mapConfiguration.zoomControlsEnabled, false);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -408,7 +384,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.zoomControlsEnabled, true);
|
||||
expect(map.mapConfiguration.zoomControlsEnabled, true);
|
||||
});
|
||||
|
||||
testWidgets('Can update myLocationEnabled', (WidgetTester tester) async {
|
||||
@ -421,10 +397,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.myLocationEnabled, false);
|
||||
expect(map.mapConfiguration.myLocationEnabled, false);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -436,7 +411,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.myLocationEnabled, true);
|
||||
expect(map.mapConfiguration.myLocationEnabled, true);
|
||||
});
|
||||
|
||||
testWidgets('Can update myLocationButtonEnabled',
|
||||
@ -450,10 +425,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.myLocationButtonEnabled, true);
|
||||
expect(map.mapConfiguration.myLocationButtonEnabled, true);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -465,7 +439,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.myLocationButtonEnabled, false);
|
||||
expect(map.mapConfiguration.myLocationButtonEnabled, false);
|
||||
});
|
||||
|
||||
testWidgets('Is default padding 0', (WidgetTester tester) async {
|
||||
@ -478,10 +452,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.padding, <double>[0, 0, 0, 0]);
|
||||
expect(map.mapConfiguration.padding, EdgeInsets.zero);
|
||||
});
|
||||
|
||||
testWidgets('Can update padding', (WidgetTester tester) async {
|
||||
@ -494,10 +467,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.padding, <double>[0, 0, 0, 0]);
|
||||
expect(map.mapConfiguration.padding, EdgeInsets.zero);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -509,7 +481,8 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.padding, <double>[20, 10, 40, 30]);
|
||||
expect(map.mapConfiguration.padding,
|
||||
const EdgeInsets.fromLTRB(10, 20, 30, 40));
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -521,7 +494,8 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.padding, <double>[60, 50, 80, 70]);
|
||||
expect(map.mapConfiguration.padding,
|
||||
const EdgeInsets.fromLTRB(50, 60, 70, 80));
|
||||
});
|
||||
|
||||
testWidgets('Can update traffic', (WidgetTester tester) async {
|
||||
@ -534,10 +508,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.trafficEnabled, false);
|
||||
expect(map.mapConfiguration.trafficEnabled, false);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -549,7 +522,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.trafficEnabled, true);
|
||||
expect(map.mapConfiguration.trafficEnabled, true);
|
||||
});
|
||||
|
||||
testWidgets('Can update buildings', (WidgetTester tester) async {
|
||||
@ -563,10 +536,9 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.buildingsEnabled, false);
|
||||
expect(map.mapConfiguration.buildingsEnabled, false);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
@ -577,12 +549,6 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(platformGoogleMap.buildingsEnabled, true);
|
||||
expect(map.mapConfiguration.buildingsEnabled, true);
|
||||
});
|
||||
}
|
||||
|
||||
/// This allows a value of type T or T? to be treated as a value of type T?.
|
||||
///
|
||||
/// We use this so that APIs that have become non-nullable can still be used
|
||||
/// with `!` and `?` on the stable branch.
|
||||
T? _ambiguate<T>(T? value) => value;
|
||||
|
@ -2,22 +2,20 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
|
||||
import 'package:stream_transform/stream_transform.dart';
|
||||
|
||||
import 'fake_google_maps_flutter_platform.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
late TestGoogleMapsFlutterPlatform platform;
|
||||
late FakeGoogleMapsFlutterPlatform platform;
|
||||
|
||||
setUp(() {
|
||||
// Use a mock platform so we never need to hit the MethodChannel code.
|
||||
platform = TestGoogleMapsFlutterPlatform();
|
||||
platform = FakeGoogleMapsFlutterPlatform();
|
||||
GoogleMapsFlutterPlatform.instance = platform;
|
||||
});
|
||||
|
||||
@ -66,222 +64,3 @@ void main() {
|
||||
expect(platform.disposed, true);
|
||||
});
|
||||
}
|
||||
|
||||
// A dummy implementation of the platform interface for tests.
|
||||
class TestGoogleMapsFlutterPlatform extends GoogleMapsFlutterPlatform {
|
||||
TestGoogleMapsFlutterPlatform();
|
||||
|
||||
// The IDs passed to each call to buildView, in call order.
|
||||
List<int> createdIds = <int>[];
|
||||
|
||||
// Whether `dispose` has been called.
|
||||
bool disposed = false;
|
||||
|
||||
// Stream controller to inject events for testing.
|
||||
final StreamController<MapEvent<dynamic>> mapEventStreamController =
|
||||
StreamController<MapEvent<dynamic>>.broadcast();
|
||||
|
||||
@override
|
||||
Future<void> init(int mapId) async {}
|
||||
|
||||
@override
|
||||
Future<void> updateMapConfiguration(
|
||||
MapConfiguration update, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> updateMarkers(
|
||||
MarkerUpdates markerUpdates, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> updatePolygons(
|
||||
PolygonUpdates polygonUpdates, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> updatePolylines(
|
||||
PolylineUpdates polylineUpdates, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> updateCircles(
|
||||
CircleUpdates circleUpdates, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> updateTileOverlays({
|
||||
required Set<TileOverlay> newTileOverlays,
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> clearTileCache(
|
||||
TileOverlayId tileOverlayId, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> animateCamera(
|
||||
CameraUpdate cameraUpdate, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> moveCamera(
|
||||
CameraUpdate cameraUpdate, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> setMapStyle(
|
||||
String? mapStyle, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<LatLngBounds> getVisibleRegion({
|
||||
required int mapId,
|
||||
}) async {
|
||||
return LatLngBounds(
|
||||
southwest: const LatLng(0, 0), northeast: const LatLng(0, 0));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ScreenCoordinate> getScreenCoordinate(
|
||||
LatLng latLng, {
|
||||
required int mapId,
|
||||
}) async {
|
||||
return const ScreenCoordinate(x: 0, y: 0);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LatLng> getLatLng(
|
||||
ScreenCoordinate screenCoordinate, {
|
||||
required int mapId,
|
||||
}) async {
|
||||
return const LatLng(0, 0);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> showMarkerInfoWindow(
|
||||
MarkerId markerId, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> hideMarkerInfoWindow(
|
||||
MarkerId markerId, {
|
||||
required int mapId,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<bool> isMarkerInfoWindowShown(
|
||||
MarkerId markerId, {
|
||||
required int mapId,
|
||||
}) async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<double> getZoomLevel({
|
||||
required int mapId,
|
||||
}) async {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List?> takeSnapshot({
|
||||
required int mapId,
|
||||
}) async {
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<CameraMoveStartedEvent> onCameraMoveStarted({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<CameraMoveStartedEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<CameraMoveEvent> onCameraMove({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<CameraMoveEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<CameraIdleEvent> onCameraIdle({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<CameraIdleEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<MarkerTapEvent> onMarkerTap({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<MarkerTapEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<InfoWindowTapEvent> onInfoWindowTap({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<InfoWindowTapEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<MarkerDragStartEvent> onMarkerDragStart({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<MarkerDragStartEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<MarkerDragEvent> onMarkerDrag({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<MarkerDragEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<MarkerDragEndEvent> onMarkerDragEnd({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<MarkerDragEndEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<PolylineTapEvent> onPolylineTap({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<PolylineTapEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<PolygonTapEvent> onPolygonTap({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<PolygonTapEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<CircleTapEvent> onCircleTap({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<CircleTapEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<MapTapEvent> onTap({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<MapTapEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<MapLongPressEvent> onLongPress({required int mapId}) {
|
||||
return mapEventStreamController.stream.whereType<MapLongPressEvent>();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose({required int mapId}) {
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildViewWithConfiguration(
|
||||
int creationId,
|
||||
PlatformViewCreatedCallback onPlatformViewCreated, {
|
||||
required MapWidgetConfiguration widgetConfiguration,
|
||||
MapObjects mapObjects = const MapObjects(),
|
||||
MapConfiguration mapConfiguration = const MapConfiguration(),
|
||||
}) {
|
||||
onPlatformViewCreated(0);
|
||||
createdIds.add(creationId);
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
|
||||
|
||||
import 'fake_maps_controllers.dart';
|
||||
import 'fake_google_maps_flutter_platform.dart';
|
||||
|
||||
Widget _mapWithMarkers(Set<Marker> markers) {
|
||||
return Directionality(
|
||||
@ -20,36 +20,24 @@ Widget _mapWithMarkers(Set<Marker> markers) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final FakePlatformViewsController fakePlatformViewsController =
|
||||
FakePlatformViewsController();
|
||||
|
||||
setUpAll(() {
|
||||
_ambiguate(TestDefaultBinaryMessengerBinding.instance)!
|
||||
.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(
|
||||
SystemChannels.platform_views,
|
||||
fakePlatformViewsController.fakePlatformViewsMethodHandler,
|
||||
);
|
||||
});
|
||||
late FakeGoogleMapsFlutterPlatform platform;
|
||||
|
||||
setUp(() {
|
||||
fakePlatformViewsController.reset();
|
||||
platform = FakeGoogleMapsFlutterPlatform();
|
||||
GoogleMapsFlutterPlatform.instance = platform;
|
||||
});
|
||||
|
||||
testWidgets('Initializing a marker', (WidgetTester tester) async {
|
||||
const Marker m1 = Marker(markerId: MarkerId('marker_1'));
|
||||
await tester.pumpWidget(_mapWithMarkers(<Marker>{m1}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.markersToAdd.length, 1);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.markerUpdates.last.markersToAdd.length, 1);
|
||||
|
||||
final Marker initializedMarker = platformGoogleMap.markersToAdd.first;
|
||||
final Marker initializedMarker = map.markerUpdates.last.markersToAdd.first;
|
||||
expect(initializedMarker, equals(m1));
|
||||
expect(platformGoogleMap.markerIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.markersToChange.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markerIdsToRemove.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markersToChange.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Adding a marker', (WidgetTester tester) async {
|
||||
@ -59,16 +47,15 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithMarkers(<Marker>{m1}));
|
||||
await tester.pumpWidget(_mapWithMarkers(<Marker>{m1, m2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.markersToAdd.length, 1);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.markerUpdates.last.markersToAdd.length, 1);
|
||||
|
||||
final Marker addedMarker = platformGoogleMap.markersToAdd.first;
|
||||
final Marker addedMarker = map.markerUpdates.last.markersToAdd.first;
|
||||
expect(addedMarker, equals(m2));
|
||||
|
||||
expect(platformGoogleMap.markerIdsToRemove.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markerIdsToRemove.isEmpty, true);
|
||||
|
||||
expect(platformGoogleMap.markersToChange.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markersToChange.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Removing a marker', (WidgetTester tester) async {
|
||||
@ -77,13 +64,12 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithMarkers(<Marker>{m1}));
|
||||
await tester.pumpWidget(_mapWithMarkers(<Marker>{}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.markerIdsToRemove.length, 1);
|
||||
expect(platformGoogleMap.markerIdsToRemove.first, equals(m1.markerId));
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.markerUpdates.last.markerIdsToRemove.length, 1);
|
||||
expect(map.markerUpdates.last.markerIdsToRemove.first, equals(m1.markerId));
|
||||
|
||||
expect(platformGoogleMap.markersToChange.isEmpty, true);
|
||||
expect(platformGoogleMap.markersToAdd.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markersToChange.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markersToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Updating a marker', (WidgetTester tester) async {
|
||||
@ -93,13 +79,12 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithMarkers(<Marker>{m1}));
|
||||
await tester.pumpWidget(_mapWithMarkers(<Marker>{m2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.markersToChange.length, 1);
|
||||
expect(platformGoogleMap.markersToChange.first, equals(m2));
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.markerUpdates.last.markersToChange.length, 1);
|
||||
expect(map.markerUpdates.last.markersToChange.first, equals(m2));
|
||||
|
||||
expect(platformGoogleMap.markerIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.markersToAdd.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markerIdsToRemove.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markersToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Updating a marker', (WidgetTester tester) async {
|
||||
@ -112,11 +97,10 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithMarkers(<Marker>{m1}));
|
||||
await tester.pumpWidget(_mapWithMarkers(<Marker>{m2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.markersToChange.length, 1);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.markerUpdates.last.markersToChange.length, 1);
|
||||
|
||||
final Marker update = platformGoogleMap.markersToChange.first;
|
||||
final Marker update = map.markerUpdates.last.markersToChange.first;
|
||||
expect(update, equals(m2));
|
||||
expect(update.infoWindow.snippet, 'changed');
|
||||
});
|
||||
@ -132,12 +116,11 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithMarkers(prev));
|
||||
await tester.pumpWidget(_mapWithMarkers(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.markersToChange, cur);
|
||||
expect(platformGoogleMap.markerIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.markersToAdd.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markersToChange, cur);
|
||||
expect(map.markerUpdates.last.markerIdsToRemove.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markersToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Multi Update', (WidgetTester tester) async {
|
||||
@ -153,16 +136,15 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithMarkers(prev));
|
||||
await tester.pumpWidget(_mapWithMarkers(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.markersToChange.length, 1);
|
||||
expect(platformGoogleMap.markersToAdd.length, 1);
|
||||
expect(platformGoogleMap.markerIdsToRemove.length, 1);
|
||||
expect(map.markerUpdates.last.markersToChange.length, 1);
|
||||
expect(map.markerUpdates.last.markersToAdd.length, 1);
|
||||
expect(map.markerUpdates.last.markerIdsToRemove.length, 1);
|
||||
|
||||
expect(platformGoogleMap.markersToChange.first, equals(m2));
|
||||
expect(platformGoogleMap.markersToAdd.first, equals(m1));
|
||||
expect(platformGoogleMap.markerIdsToRemove.first, equals(m3.markerId));
|
||||
expect(map.markerUpdates.last.markersToChange.first, equals(m2));
|
||||
expect(map.markerUpdates.last.markersToAdd.first, equals(m1));
|
||||
expect(map.markerUpdates.last.markerIdsToRemove.first, equals(m3.markerId));
|
||||
});
|
||||
|
||||
testWidgets('Partial Update', (WidgetTester tester) async {
|
||||
@ -176,12 +158,11 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithMarkers(prev));
|
||||
await tester.pumpWidget(_mapWithMarkers(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.markersToChange, <Marker>{m3});
|
||||
expect(platformGoogleMap.markerIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.markersToAdd.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markersToChange, <Marker>{m3});
|
||||
expect(map.markerUpdates.last.markerIdsToRemove.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markersToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Update non platform related attr', (WidgetTester tester) async {
|
||||
@ -196,17 +177,43 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithMarkers(prev));
|
||||
await tester.pumpWidget(_mapWithMarkers(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.markersToChange.isEmpty, true);
|
||||
expect(platformGoogleMap.markerIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.markersToAdd.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markersToChange.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markerIdsToRemove.isEmpty, true);
|
||||
expect(map.markerUpdates.last.markersToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('multi-update with delays', (WidgetTester tester) async {
|
||||
platform.simulatePlatformDelay = true;
|
||||
|
||||
const Marker m1 = Marker(markerId: MarkerId('marker_1'));
|
||||
const Marker m2 = Marker(markerId: MarkerId('marker_2'));
|
||||
const Marker m3 = Marker(markerId: MarkerId('marker_3'));
|
||||
const Marker m3updated =
|
||||
Marker(markerId: MarkerId('marker_3'), draggable: true);
|
||||
|
||||
// First remove one and add another, then update the new one.
|
||||
await tester.pumpWidget(_mapWithMarkers(<Marker>{m1, m2}));
|
||||
await tester.pumpWidget(_mapWithMarkers(<Marker>{m1, m3}));
|
||||
await tester.pumpWidget(_mapWithMarkers(<Marker>{m1, m3updated}));
|
||||
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(map.markerUpdates.length, 3);
|
||||
|
||||
expect(map.markerUpdates[0].markersToChange.isEmpty, true);
|
||||
expect(map.markerUpdates[0].markersToAdd, <Marker>{m1, m2});
|
||||
expect(map.markerUpdates[0].markerIdsToRemove.isEmpty, true);
|
||||
|
||||
expect(map.markerUpdates[1].markersToChange.isEmpty, true);
|
||||
expect(map.markerUpdates[1].markersToAdd, <Marker>{m3});
|
||||
expect(map.markerUpdates[1].markerIdsToRemove, <MarkerId>{m2.markerId});
|
||||
|
||||
expect(map.markerUpdates[2].markersToChange, <Marker>{m3updated});
|
||||
expect(map.markerUpdates[2].markersToAdd.isEmpty, true);
|
||||
expect(map.markerUpdates[2].markerIdsToRemove.isEmpty, true);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
}
|
||||
|
||||
/// This allows a value of type T or T? to be treated as a value of type T?.
|
||||
///
|
||||
/// We use this so that APIs that have become non-nullable can still be used
|
||||
/// with `!` and `?` on the stable branch.
|
||||
T? _ambiguate<T>(T? value) => value;
|
||||
|
@ -2,12 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
|
||||
|
||||
import 'fake_maps_controllers.dart';
|
||||
import 'fake_google_maps_flutter_platform.dart';
|
||||
|
||||
Widget _mapWithPolygons(Set<Polygon> polygons) {
|
||||
return Directionality(
|
||||
@ -43,36 +43,25 @@ Polygon _polygonWithPointsAndHole(PolygonId polygonId) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final FakePlatformViewsController fakePlatformViewsController =
|
||||
FakePlatformViewsController();
|
||||
|
||||
setUpAll(() {
|
||||
_ambiguate(TestDefaultBinaryMessengerBinding.instance)!
|
||||
.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(
|
||||
SystemChannels.platform_views,
|
||||
fakePlatformViewsController.fakePlatformViewsMethodHandler,
|
||||
);
|
||||
});
|
||||
late FakeGoogleMapsFlutterPlatform platform;
|
||||
|
||||
setUp(() {
|
||||
fakePlatformViewsController.reset();
|
||||
platform = FakeGoogleMapsFlutterPlatform();
|
||||
GoogleMapsFlutterPlatform.instance = platform;
|
||||
});
|
||||
|
||||
testWidgets('Initializing a polygon', (WidgetTester tester) async {
|
||||
const Polygon p1 = Polygon(polygonId: PolygonId('polygon_1'));
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polygonsToAdd.length, 1);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.length, 1);
|
||||
|
||||
final Polygon initializedPolygon = platformGoogleMap.polygonsToAdd.first;
|
||||
final Polygon initializedPolygon =
|
||||
map.polygonUpdates.last.polygonsToAdd.first;
|
||||
expect(initializedPolygon, equals(p1));
|
||||
expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonsToChange.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToChange.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Adding a polygon', (WidgetTester tester) async {
|
||||
@ -82,16 +71,15 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1}));
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1, p2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polygonsToAdd.length, 1);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.length, 1);
|
||||
|
||||
final Polygon addedPolygon = platformGoogleMap.polygonsToAdd.first;
|
||||
final Polygon addedPolygon = map.polygonUpdates.last.polygonsToAdd.first;
|
||||
expect(addedPolygon, equals(p2));
|
||||
|
||||
expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.isEmpty, true);
|
||||
|
||||
expect(platformGoogleMap.polygonsToChange.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToChange.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Removing a polygon', (WidgetTester tester) async {
|
||||
@ -100,13 +88,13 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1}));
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polygonIdsToRemove.length, 1);
|
||||
expect(platformGoogleMap.polygonIdsToRemove.first, equals(p1.polygonId));
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.length, 1);
|
||||
expect(
|
||||
map.polygonUpdates.last.polygonIdsToRemove.first, equals(p1.polygonId));
|
||||
|
||||
expect(platformGoogleMap.polygonsToChange.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonsToAdd.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToChange.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Updating a polygon', (WidgetTester tester) async {
|
||||
@ -117,13 +105,12 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1}));
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polygonsToChange.length, 1);
|
||||
expect(platformGoogleMap.polygonsToChange.first, equals(p2));
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polygonUpdates.last.polygonsToChange.length, 1);
|
||||
expect(map.polygonUpdates.last.polygonsToChange.first, equals(p2));
|
||||
|
||||
expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonsToAdd.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Mutate a polygon', (WidgetTester tester) async {
|
||||
@ -137,13 +124,12 @@ void main() {
|
||||
p1.points.add(const LatLng(1.0, 1.0));
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polygonsToChange.length, 1);
|
||||
expect(platformGoogleMap.polygonsToChange.first, equals(p1));
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polygonUpdates.last.polygonsToChange.length, 1);
|
||||
expect(map.polygonUpdates.last.polygonsToChange.first, equals(p1));
|
||||
|
||||
expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonsToAdd.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Multi Update', (WidgetTester tester) async {
|
||||
@ -157,12 +143,11 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolygons(prev));
|
||||
await tester.pumpWidget(_mapWithPolygons(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.polygonsToChange, cur);
|
||||
expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonsToAdd.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToChange, cur);
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Multi Update', (WidgetTester tester) async {
|
||||
@ -178,16 +163,16 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolygons(prev));
|
||||
await tester.pumpWidget(_mapWithPolygons(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.polygonsToChange.length, 1);
|
||||
expect(platformGoogleMap.polygonsToAdd.length, 1);
|
||||
expect(platformGoogleMap.polygonIdsToRemove.length, 1);
|
||||
expect(map.polygonUpdates.last.polygonsToChange.length, 1);
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.length, 1);
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.length, 1);
|
||||
|
||||
expect(platformGoogleMap.polygonsToChange.first, equals(p2));
|
||||
expect(platformGoogleMap.polygonsToAdd.first, equals(p1));
|
||||
expect(platformGoogleMap.polygonIdsToRemove.first, equals(p3.polygonId));
|
||||
expect(map.polygonUpdates.last.polygonsToChange.first, equals(p2));
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.first, equals(p1));
|
||||
expect(
|
||||
map.polygonUpdates.last.polygonIdsToRemove.first, equals(p3.polygonId));
|
||||
});
|
||||
|
||||
testWidgets('Partial Update', (WidgetTester tester) async {
|
||||
@ -201,12 +186,11 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolygons(prev));
|
||||
await tester.pumpWidget(_mapWithPolygons(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.polygonsToChange, <Polygon>{p3});
|
||||
expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonsToAdd.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToChange, <Polygon>{p3});
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Update non platform related attr', (WidgetTester tester) async {
|
||||
@ -218,12 +202,11 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolygons(prev));
|
||||
await tester.pumpWidget(_mapWithPolygons(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.polygonsToChange.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonsToAdd.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToChange.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Initializing a polygon with points and hole',
|
||||
@ -231,14 +214,14 @@ void main() {
|
||||
final Polygon p1 = _polygonWithPointsAndHole(const PolygonId('polygon_1'));
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polygonsToAdd.length, 1);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.length, 1);
|
||||
|
||||
final Polygon initializedPolygon = platformGoogleMap.polygonsToAdd.first;
|
||||
final Polygon initializedPolygon =
|
||||
map.polygonUpdates.last.polygonsToAdd.first;
|
||||
expect(initializedPolygon, equals(p1));
|
||||
expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonsToChange.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToChange.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Adding a polygon with points and hole',
|
||||
@ -249,16 +232,15 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1}));
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1, p2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polygonsToAdd.length, 1);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.length, 1);
|
||||
|
||||
final Polygon addedPolygon = platformGoogleMap.polygonsToAdd.first;
|
||||
final Polygon addedPolygon = map.polygonUpdates.last.polygonsToAdd.first;
|
||||
expect(addedPolygon, equals(p2));
|
||||
|
||||
expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.isEmpty, true);
|
||||
|
||||
expect(platformGoogleMap.polygonsToChange.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToChange.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Removing a polygon with points and hole',
|
||||
@ -268,13 +250,13 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1}));
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polygonIdsToRemove.length, 1);
|
||||
expect(platformGoogleMap.polygonIdsToRemove.first, equals(p1.polygonId));
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.length, 1);
|
||||
expect(
|
||||
map.polygonUpdates.last.polygonIdsToRemove.first, equals(p1.polygonId));
|
||||
|
||||
expect(platformGoogleMap.polygonsToChange.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonsToAdd.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToChange.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Updating a polygon by adding points and hole',
|
||||
@ -285,13 +267,12 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1}));
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polygonsToChange.length, 1);
|
||||
expect(platformGoogleMap.polygonsToChange.first, equals(p2));
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polygonUpdates.last.polygonsToChange.length, 1);
|
||||
expect(map.polygonUpdates.last.polygonsToChange.first, equals(p2));
|
||||
|
||||
expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonsToAdd.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Mutate a polygon with points and holes',
|
||||
@ -311,13 +292,12 @@ void main() {
|
||||
..addAll(<List<LatLng>>[_rectPoints(size: 1)]);
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polygonsToChange.length, 1);
|
||||
expect(platformGoogleMap.polygonsToChange.first, equals(p1));
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polygonUpdates.last.polygonsToChange.length, 1);
|
||||
expect(map.polygonUpdates.last.polygonsToChange.first, equals(p1));
|
||||
|
||||
expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonsToAdd.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Multi Update polygons with points and hole',
|
||||
@ -339,12 +319,11 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolygons(prev));
|
||||
await tester.pumpWidget(_mapWithPolygons(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.polygonsToChange, cur);
|
||||
expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonsToAdd.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToChange, cur);
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Multi Update polygons with points and hole',
|
||||
@ -368,16 +347,16 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolygons(prev));
|
||||
await tester.pumpWidget(_mapWithPolygons(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.polygonsToChange.length, 1);
|
||||
expect(platformGoogleMap.polygonsToAdd.length, 1);
|
||||
expect(platformGoogleMap.polygonIdsToRemove.length, 1);
|
||||
expect(map.polygonUpdates.last.polygonsToChange.length, 1);
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.length, 1);
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.length, 1);
|
||||
|
||||
expect(platformGoogleMap.polygonsToChange.first, equals(p2));
|
||||
expect(platformGoogleMap.polygonsToAdd.first, equals(p1));
|
||||
expect(platformGoogleMap.polygonIdsToRemove.first, equals(p3.polygonId));
|
||||
expect(map.polygonUpdates.last.polygonsToChange.first, equals(p2));
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.first, equals(p1));
|
||||
expect(
|
||||
map.polygonUpdates.last.polygonIdsToRemove.first, equals(p3.polygonId));
|
||||
});
|
||||
|
||||
testWidgets('Partial Update polygons with points and hole',
|
||||
@ -399,17 +378,44 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolygons(prev));
|
||||
await tester.pumpWidget(_mapWithPolygons(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.polygonsToChange, <Polygon>{p3});
|
||||
expect(platformGoogleMap.polygonIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polygonsToAdd.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToChange, <Polygon>{p3});
|
||||
expect(map.polygonUpdates.last.polygonIdsToRemove.isEmpty, true);
|
||||
expect(map.polygonUpdates.last.polygonsToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('multi-update with delays', (WidgetTester tester) async {
|
||||
platform.simulatePlatformDelay = true;
|
||||
|
||||
const Polygon p1 = Polygon(polygonId: PolygonId('polygon_1'));
|
||||
const Polygon p2 = Polygon(polygonId: PolygonId('polygon_2'));
|
||||
const Polygon p3 =
|
||||
Polygon(polygonId: PolygonId('polygon_3'), strokeWidth: 1);
|
||||
const Polygon p3updated =
|
||||
Polygon(polygonId: PolygonId('polygon_3'), strokeWidth: 2);
|
||||
|
||||
// First remove one and add another, then update the new one.
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1, p2}));
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1, p3}));
|
||||
await tester.pumpWidget(_mapWithPolygons(<Polygon>{p1, p3updated}));
|
||||
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(map.polygonUpdates.length, 3);
|
||||
|
||||
expect(map.polygonUpdates[0].polygonsToChange.isEmpty, true);
|
||||
expect(map.polygonUpdates[0].polygonsToAdd, <Polygon>{p1, p2});
|
||||
expect(map.polygonUpdates[0].polygonIdsToRemove.isEmpty, true);
|
||||
|
||||
expect(map.polygonUpdates[1].polygonsToChange.isEmpty, true);
|
||||
expect(map.polygonUpdates[1].polygonsToAdd, <Polygon>{p3});
|
||||
expect(map.polygonUpdates[1].polygonIdsToRemove, <PolygonId>{p2.polygonId});
|
||||
|
||||
expect(map.polygonUpdates[2].polygonsToChange, <Polygon>{p3updated});
|
||||
expect(map.polygonUpdates[2].polygonsToAdd.isEmpty, true);
|
||||
expect(map.polygonUpdates[2].polygonIdsToRemove.isEmpty, true);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
}
|
||||
|
||||
/// This allows a value of type T or T? to be treated as a value of type T?.
|
||||
///
|
||||
/// We use this so that APIs that have become non-nullable can still be used
|
||||
/// with `!` and `?` on the stable branch.
|
||||
T? _ambiguate<T>(T? value) => value;
|
||||
|
@ -2,12 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
|
||||
|
||||
import 'fake_maps_controllers.dart';
|
||||
import 'fake_google_maps_flutter_platform.dart';
|
||||
|
||||
Widget _mapWithPolylines(Set<Polyline> polylines) {
|
||||
return Directionality(
|
||||
@ -20,36 +20,25 @@ Widget _mapWithPolylines(Set<Polyline> polylines) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final FakePlatformViewsController fakePlatformViewsController =
|
||||
FakePlatformViewsController();
|
||||
|
||||
setUpAll(() {
|
||||
_ambiguate(TestDefaultBinaryMessengerBinding.instance)!
|
||||
.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(
|
||||
SystemChannels.platform_views,
|
||||
fakePlatformViewsController.fakePlatformViewsMethodHandler,
|
||||
);
|
||||
});
|
||||
late FakeGoogleMapsFlutterPlatform platform;
|
||||
|
||||
setUp(() {
|
||||
fakePlatformViewsController.reset();
|
||||
platform = FakeGoogleMapsFlutterPlatform();
|
||||
GoogleMapsFlutterPlatform.instance = platform;
|
||||
});
|
||||
|
||||
testWidgets('Initializing a polyline', (WidgetTester tester) async {
|
||||
const Polyline p1 = Polyline(polylineId: PolylineId('polyline_1'));
|
||||
await tester.pumpWidget(_mapWithPolylines(<Polyline>{p1}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polylinesToAdd.length, 1);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polylineUpdates.last.polylinesToAdd.length, 1);
|
||||
|
||||
final Polyline initializedPolyline = platformGoogleMap.polylinesToAdd.first;
|
||||
final Polyline initializedPolyline =
|
||||
map.polylineUpdates.last.polylinesToAdd.first;
|
||||
expect(initializedPolyline, equals(p1));
|
||||
expect(platformGoogleMap.polylineIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polylinesToChange.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylineIdsToRemove.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylinesToChange.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Adding a polyline', (WidgetTester tester) async {
|
||||
@ -59,16 +48,16 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolylines(<Polyline>{p1}));
|
||||
await tester.pumpWidget(_mapWithPolylines(<Polyline>{p1, p2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polylinesToAdd.length, 1);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polylineUpdates.last.polylinesToAdd.length, 1);
|
||||
|
||||
final Polyline addedPolyline = platformGoogleMap.polylinesToAdd.first;
|
||||
final Polyline addedPolyline =
|
||||
map.polylineUpdates.last.polylinesToAdd.first;
|
||||
expect(addedPolyline, equals(p2));
|
||||
|
||||
expect(platformGoogleMap.polylineIdsToRemove.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylineIdsToRemove.isEmpty, true);
|
||||
|
||||
expect(platformGoogleMap.polylinesToChange.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylinesToChange.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Removing a polyline', (WidgetTester tester) async {
|
||||
@ -77,13 +66,13 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolylines(<Polyline>{p1}));
|
||||
await tester.pumpWidget(_mapWithPolylines(<Polyline>{}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polylineIdsToRemove.length, 1);
|
||||
expect(platformGoogleMap.polylineIdsToRemove.first, equals(p1.polylineId));
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polylineUpdates.last.polylineIdsToRemove.length, 1);
|
||||
expect(map.polylineUpdates.last.polylineIdsToRemove.first,
|
||||
equals(p1.polylineId));
|
||||
|
||||
expect(platformGoogleMap.polylinesToChange.isEmpty, true);
|
||||
expect(platformGoogleMap.polylinesToAdd.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylinesToChange.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylinesToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Updating a polyline', (WidgetTester tester) async {
|
||||
@ -94,13 +83,12 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolylines(<Polyline>{p1}));
|
||||
await tester.pumpWidget(_mapWithPolylines(<Polyline>{p2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polylinesToChange.length, 1);
|
||||
expect(platformGoogleMap.polylinesToChange.first, equals(p2));
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polylineUpdates.last.polylinesToChange.length, 1);
|
||||
expect(map.polylineUpdates.last.polylinesToChange.first, equals(p2));
|
||||
|
||||
expect(platformGoogleMap.polylineIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polylinesToAdd.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylineIdsToRemove.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylinesToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Updating a polyline', (WidgetTester tester) async {
|
||||
@ -111,11 +99,10 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolylines(<Polyline>{p1}));
|
||||
await tester.pumpWidget(_mapWithPolylines(<Polyline>{p2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polylinesToChange.length, 1);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polylineUpdates.last.polylinesToChange.length, 1);
|
||||
|
||||
final Polyline update = platformGoogleMap.polylinesToChange.first;
|
||||
final Polyline update = map.polylineUpdates.last.polylinesToChange.first;
|
||||
expect(update, equals(p2));
|
||||
expect(update.geodesic, true);
|
||||
});
|
||||
@ -131,13 +118,12 @@ void main() {
|
||||
p1.points.add(const LatLng(1.0, 1.0));
|
||||
await tester.pumpWidget(_mapWithPolylines(<Polyline>{p1}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.polylinesToChange.length, 1);
|
||||
expect(platformGoogleMap.polylinesToChange.first, equals(p1));
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.polylineUpdates.last.polylinesToChange.length, 1);
|
||||
expect(map.polylineUpdates.last.polylinesToChange.first, equals(p1));
|
||||
|
||||
expect(platformGoogleMap.polylineIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polylinesToAdd.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylineIdsToRemove.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylinesToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Multi Update', (WidgetTester tester) async {
|
||||
@ -151,12 +137,11 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolylines(prev));
|
||||
await tester.pumpWidget(_mapWithPolylines(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.polylinesToChange, cur);
|
||||
expect(platformGoogleMap.polylineIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polylinesToAdd.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylinesToChange, cur);
|
||||
expect(map.polylineUpdates.last.polylineIdsToRemove.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylinesToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Multi Update', (WidgetTester tester) async {
|
||||
@ -172,16 +157,16 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolylines(prev));
|
||||
await tester.pumpWidget(_mapWithPolylines(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.polylinesToChange.length, 1);
|
||||
expect(platformGoogleMap.polylinesToAdd.length, 1);
|
||||
expect(platformGoogleMap.polylineIdsToRemove.length, 1);
|
||||
expect(map.polylineUpdates.last.polylinesToChange.length, 1);
|
||||
expect(map.polylineUpdates.last.polylinesToAdd.length, 1);
|
||||
expect(map.polylineUpdates.last.polylineIdsToRemove.length, 1);
|
||||
|
||||
expect(platformGoogleMap.polylinesToChange.first, equals(p2));
|
||||
expect(platformGoogleMap.polylinesToAdd.first, equals(p1));
|
||||
expect(platformGoogleMap.polylineIdsToRemove.first, equals(p3.polylineId));
|
||||
expect(map.polylineUpdates.last.polylinesToChange.first, equals(p2));
|
||||
expect(map.polylineUpdates.last.polylinesToAdd.first, equals(p1));
|
||||
expect(map.polylineUpdates.last.polylineIdsToRemove.first,
|
||||
equals(p3.polylineId));
|
||||
});
|
||||
|
||||
testWidgets('Partial Update', (WidgetTester tester) async {
|
||||
@ -195,12 +180,11 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolylines(prev));
|
||||
await tester.pumpWidget(_mapWithPolylines(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.polylinesToChange, <Polyline>{p3});
|
||||
expect(platformGoogleMap.polylineIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polylinesToAdd.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylinesToChange, <Polyline>{p3});
|
||||
expect(map.polylineUpdates.last.polylineIdsToRemove.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylinesToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Update non platform related attr', (WidgetTester tester) async {
|
||||
@ -212,17 +196,45 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithPolylines(prev));
|
||||
await tester.pumpWidget(_mapWithPolylines(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(platformGoogleMap.polylinesToChange.isEmpty, true);
|
||||
expect(platformGoogleMap.polylineIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.polylinesToAdd.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylinesToChange.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylineIdsToRemove.isEmpty, true);
|
||||
expect(map.polylineUpdates.last.polylinesToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('multi-update with delays', (WidgetTester tester) async {
|
||||
platform.simulatePlatformDelay = true;
|
||||
|
||||
const Polyline p1 = Polyline(polylineId: PolylineId('polyline_1'));
|
||||
const Polyline p2 = Polyline(polylineId: PolylineId('polyline_2'));
|
||||
const Polyline p3 =
|
||||
Polyline(polylineId: PolylineId('polyline_3'), width: 1);
|
||||
const Polyline p3updated =
|
||||
Polyline(polylineId: PolylineId('polyline_3'), width: 2);
|
||||
|
||||
// First remove one and add another, then update the new one.
|
||||
await tester.pumpWidget(_mapWithPolylines(<Polyline>{p1, p2}));
|
||||
await tester.pumpWidget(_mapWithPolylines(<Polyline>{p1, p3}));
|
||||
await tester.pumpWidget(_mapWithPolylines(<Polyline>{p1, p3updated}));
|
||||
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
|
||||
expect(map.polylineUpdates.length, 3);
|
||||
|
||||
expect(map.polylineUpdates[0].polylinesToChange.isEmpty, true);
|
||||
expect(map.polylineUpdates[0].polylinesToAdd, <Polyline>{p1, p2});
|
||||
expect(map.polylineUpdates[0].polylineIdsToRemove.isEmpty, true);
|
||||
|
||||
expect(map.polylineUpdates[1].polylinesToChange.isEmpty, true);
|
||||
expect(map.polylineUpdates[1].polylinesToAdd, <Polyline>{p3});
|
||||
expect(map.polylineUpdates[1].polylineIdsToRemove,
|
||||
<PolylineId>{p2.polylineId});
|
||||
|
||||
expect(map.polylineUpdates[2].polylinesToChange, <Polyline>{p3updated});
|
||||
expect(map.polylineUpdates[2].polylinesToAdd.isEmpty, true);
|
||||
expect(map.polylineUpdates[2].polylineIdsToRemove.isEmpty, true);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
}
|
||||
|
||||
/// This allows a value of type T or T? to be treated as a value of type T?.
|
||||
///
|
||||
/// We use this so that APIs that have become non-nullable can still be used
|
||||
/// with `!` and `?` on the stable branch.
|
||||
T? _ambiguate<T>(T? value) => value;
|
||||
|
@ -2,12 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
|
||||
|
||||
import 'fake_maps_controllers.dart';
|
||||
import 'fake_google_maps_flutter_platform.dart';
|
||||
|
||||
Widget _mapWithTileOverlays(Set<TileOverlay> tileOverlays) {
|
||||
return Directionality(
|
||||
@ -20,20 +20,11 @@ Widget _mapWithTileOverlays(Set<TileOverlay> tileOverlays) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
final FakePlatformViewsController fakePlatformViewsController =
|
||||
FakePlatformViewsController();
|
||||
|
||||
setUpAll(() {
|
||||
_ambiguate(TestDefaultBinaryMessengerBinding.instance)!
|
||||
.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(
|
||||
SystemChannels.platform_views,
|
||||
fakePlatformViewsController.fakePlatformViewsMethodHandler,
|
||||
);
|
||||
});
|
||||
late FakeGoogleMapsFlutterPlatform platform;
|
||||
|
||||
setUp(() {
|
||||
fakePlatformViewsController.reset();
|
||||
platform = FakeGoogleMapsFlutterPlatform();
|
||||
GoogleMapsFlutterPlatform.instance = platform;
|
||||
});
|
||||
|
||||
testWidgets('Initializing a tile overlay', (WidgetTester tester) async {
|
||||
@ -41,15 +32,8 @@ void main() {
|
||||
TileOverlay(tileOverlayId: TileOverlayId('tile_overlay_1'));
|
||||
await tester.pumpWidget(_mapWithTileOverlays(<TileOverlay>{t1}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.tileOverlaysToAdd.length, 1);
|
||||
|
||||
final TileOverlay initializedTileOverlay =
|
||||
platformGoogleMap.tileOverlaysToAdd.first;
|
||||
expect(initializedTileOverlay, equals(t1));
|
||||
expect(platformGoogleMap.tileOverlayIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.tileOverlaysToChange.isEmpty, true);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.tileOverlaySets.last, equals(<TileOverlay>{t1}));
|
||||
});
|
||||
|
||||
testWidgets('Adding a tile overlay', (WidgetTester tester) async {
|
||||
@ -61,16 +45,8 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithTileOverlays(<TileOverlay>{t1}));
|
||||
await tester.pumpWidget(_mapWithTileOverlays(<TileOverlay>{t1, t2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.tileOverlaysToAdd.length, 1);
|
||||
|
||||
final TileOverlay addedTileOverlay =
|
||||
platformGoogleMap.tileOverlaysToAdd.first;
|
||||
expect(addedTileOverlay, equals(t2));
|
||||
expect(platformGoogleMap.tileOverlayIdsToRemove.isEmpty, true);
|
||||
|
||||
expect(platformGoogleMap.tileOverlaysToChange.isEmpty, true);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.tileOverlaySets.last, equals(<TileOverlay>{t1, t2}));
|
||||
});
|
||||
|
||||
testWidgets('Removing a tile overlay', (WidgetTester tester) async {
|
||||
@ -80,14 +56,8 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithTileOverlays(<TileOverlay>{t1}));
|
||||
await tester.pumpWidget(_mapWithTileOverlays(<TileOverlay>{}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.tileOverlayIdsToRemove.length, 1);
|
||||
expect(platformGoogleMap.tileOverlayIdsToRemove.first,
|
||||
equals(t1.tileOverlayId));
|
||||
|
||||
expect(platformGoogleMap.tileOverlaysToChange.isEmpty, true);
|
||||
expect(platformGoogleMap.tileOverlaysToAdd.isEmpty, true);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.tileOverlaySets.last, equals(<TileOverlay>{}));
|
||||
});
|
||||
|
||||
testWidgets('Updating a tile overlay', (WidgetTester tester) async {
|
||||
@ -99,112 +69,7 @@ void main() {
|
||||
await tester.pumpWidget(_mapWithTileOverlays(<TileOverlay>{t1}));
|
||||
await tester.pumpWidget(_mapWithTileOverlays(<TileOverlay>{t2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.tileOverlaysToChange.length, 1);
|
||||
expect(platformGoogleMap.tileOverlaysToChange.first, equals(t2));
|
||||
|
||||
expect(platformGoogleMap.tileOverlayIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.tileOverlaysToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Updating a tile overlay', (WidgetTester tester) async {
|
||||
const TileOverlay t1 =
|
||||
TileOverlay(tileOverlayId: TileOverlayId('tile_overlay_1'));
|
||||
const TileOverlay t2 =
|
||||
TileOverlay(tileOverlayId: TileOverlayId('tile_overlay_1'), zIndex: 10);
|
||||
|
||||
await tester.pumpWidget(_mapWithTileOverlays(<TileOverlay>{t1}));
|
||||
await tester.pumpWidget(_mapWithTileOverlays(<TileOverlay>{t2}));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
expect(platformGoogleMap.tileOverlaysToChange.length, 1);
|
||||
|
||||
final TileOverlay update = platformGoogleMap.tileOverlaysToChange.first;
|
||||
expect(update, equals(t2));
|
||||
expect(update.zIndex, 10);
|
||||
});
|
||||
|
||||
testWidgets('Multi Update', (WidgetTester tester) async {
|
||||
TileOverlay t1 =
|
||||
const TileOverlay(tileOverlayId: TileOverlayId('tile_overlay_1'));
|
||||
TileOverlay t2 =
|
||||
const TileOverlay(tileOverlayId: TileOverlayId('tile_overlay_2'));
|
||||
final Set<TileOverlay> prev = <TileOverlay>{t1, t2};
|
||||
t1 = const TileOverlay(
|
||||
tileOverlayId: TileOverlayId('tile_overlay_1'), visible: false);
|
||||
t2 = const TileOverlay(
|
||||
tileOverlayId: TileOverlayId('tile_overlay_2'), zIndex: 10);
|
||||
final Set<TileOverlay> cur = <TileOverlay>{t1, t2};
|
||||
|
||||
await tester.pumpWidget(_mapWithTileOverlays(prev));
|
||||
await tester.pumpWidget(_mapWithTileOverlays(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
|
||||
expect(platformGoogleMap.tileOverlaysToChange, cur);
|
||||
expect(platformGoogleMap.tileOverlayIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.tileOverlaysToAdd.isEmpty, true);
|
||||
});
|
||||
|
||||
testWidgets('Multi Update', (WidgetTester tester) async {
|
||||
TileOverlay t2 =
|
||||
const TileOverlay(tileOverlayId: TileOverlayId('tile_overlay_2'));
|
||||
const TileOverlay t3 =
|
||||
TileOverlay(tileOverlayId: TileOverlayId('tile_overlay_3'));
|
||||
final Set<TileOverlay> prev = <TileOverlay>{t2, t3};
|
||||
|
||||
// t1 is added, t2 is updated, t3 is removed.
|
||||
const TileOverlay t1 =
|
||||
TileOverlay(tileOverlayId: TileOverlayId('tile_overlay_1'));
|
||||
t2 = const TileOverlay(
|
||||
tileOverlayId: TileOverlayId('tile_overlay_2'), zIndex: 10);
|
||||
final Set<TileOverlay> cur = <TileOverlay>{t1, t2};
|
||||
|
||||
await tester.pumpWidget(_mapWithTileOverlays(prev));
|
||||
await tester.pumpWidget(_mapWithTileOverlays(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
|
||||
expect(platformGoogleMap.tileOverlaysToChange.length, 1);
|
||||
expect(platformGoogleMap.tileOverlaysToAdd.length, 1);
|
||||
expect(platformGoogleMap.tileOverlayIdsToRemove.length, 1);
|
||||
|
||||
expect(platformGoogleMap.tileOverlaysToChange.first, equals(t2));
|
||||
expect(platformGoogleMap.tileOverlaysToAdd.first, equals(t1));
|
||||
expect(platformGoogleMap.tileOverlayIdsToRemove.first,
|
||||
equals(t3.tileOverlayId));
|
||||
});
|
||||
|
||||
testWidgets('Partial Update', (WidgetTester tester) async {
|
||||
const TileOverlay t1 =
|
||||
TileOverlay(tileOverlayId: TileOverlayId('tile_overlay_1'));
|
||||
const TileOverlay t2 =
|
||||
TileOverlay(tileOverlayId: TileOverlayId('tile_overlay_2'));
|
||||
TileOverlay t3 =
|
||||
const TileOverlay(tileOverlayId: TileOverlayId('tile_overlay_3'));
|
||||
final Set<TileOverlay> prev = <TileOverlay>{t1, t2, t3};
|
||||
t3 = const TileOverlay(
|
||||
tileOverlayId: TileOverlayId('tile_overlay_3'), zIndex: 10);
|
||||
final Set<TileOverlay> cur = <TileOverlay>{t1, t2, t3};
|
||||
|
||||
await tester.pumpWidget(_mapWithTileOverlays(prev));
|
||||
await tester.pumpWidget(_mapWithTileOverlays(cur));
|
||||
|
||||
final FakePlatformGoogleMap platformGoogleMap =
|
||||
fakePlatformViewsController.lastCreatedView!;
|
||||
|
||||
expect(platformGoogleMap.tileOverlaysToChange, <TileOverlay>{t3});
|
||||
expect(platformGoogleMap.tileOverlayIdsToRemove.isEmpty, true);
|
||||
expect(platformGoogleMap.tileOverlaysToAdd.isEmpty, true);
|
||||
final PlatformMapStateRecorder map = platform.lastCreatedMap;
|
||||
expect(map.tileOverlaySets.last, equals(<TileOverlay>{t2}));
|
||||
});
|
||||
}
|
||||
|
||||
/// This allows a value of type T or T? to be treated as a value of type T?.
|
||||
///
|
||||
/// We use this so that APIs that have become non-nullable can still be used
|
||||
/// with `!` and `?` on the stable branch.
|
||||
T? _ambiguate<T>(T? value) => value;
|
||||
|
@ -25,3 +25,10 @@ dev_dependencies:
|
||||
integration_test:
|
||||
sdk: flutter
|
||||
mockito: 5.4.1
|
||||
|
||||
dependency_overrides:
|
||||
# Override the google_maps_flutter dependency on google_maps_flutter_web.
|
||||
# TODO(ditman): Unwind the circular dependency. This will create problems
|
||||
# if we need to make a breaking change to google_maps_flutter_web.
|
||||
google_maps_flutter_web:
|
||||
path: ../
|
||||
|
Reference in New Issue
Block a user