3
3
// found in the LICENSE file.
4
4
5
5
import 'dart:async' ;
6
+ import 'dart:io' ;
6
7
import 'dart:ui' as ui;
7
8
8
9
import 'package:flutter/foundation.dart' ;
@@ -21,6 +22,8 @@ void main() {
21
22
}
22
23
23
24
void runTests () {
25
+ const double floatTolerance = 1e-8 ;
26
+
24
27
GoogleMapsFlutterPlatform .instance.enableDebugInspection ();
25
28
26
29
final GoogleMapsInspectorPlatform inspector =
@@ -204,6 +207,271 @@ void runTests() {
204
207
},
205
208
);
206
209
}, skip: isWeb /* Tiles not supported on the web */ );
210
+
211
+ /// Check that two lists of [WeightedLatLng] are more or less equal.
212
+ void expectHeatmapDataMoreOrLessEquals (
213
+ List <WeightedLatLng > data1,
214
+ List <WeightedLatLng > data2,
215
+ ) {
216
+ expect (data1.length, data2.length);
217
+ for (int i = 0 ; i < data1.length; i++ ) {
218
+ final WeightedLatLng wll1 = data1[i];
219
+ final WeightedLatLng wll2 = data2[i];
220
+ expect (wll1.weight, wll2.weight);
221
+ expect (wll1.point.latitude, moreOrLessEquals (wll2.point.latitude));
222
+ expect (wll1.point.longitude, moreOrLessEquals (wll2.point.longitude));
223
+ }
224
+ }
225
+
226
+ /// Check that two [HeatmapGradient] s are more or less equal.
227
+ void expectHeatmapGradientMoreOrLessEquals (
228
+ HeatmapGradient ? gradient1,
229
+ HeatmapGradient ? gradient2,
230
+ ) {
231
+ if (gradient1 == null || gradient2 == null ) {
232
+ expect (gradient1, gradient2);
233
+ return ;
234
+ }
235
+ expect (gradient2, isNotNull);
236
+
237
+ expect (gradient1.colors.length, gradient2.colors.length);
238
+ for (int i = 0 ; i < gradient1.colors.length; i++ ) {
239
+ final HeatmapGradientColor color1 = gradient1.colors[i];
240
+ final HeatmapGradientColor color2 = gradient2.colors[i];
241
+ expect (color1.color, color2.color);
242
+ expect (
243
+ color1.startPoint,
244
+ moreOrLessEquals (color2.startPoint, epsilon: floatTolerance),
245
+ );
246
+ }
247
+
248
+ expect (gradient1.colorMapSize, gradient2.colorMapSize);
249
+ }
250
+
251
+ void expectHeatmapEquals (Heatmap heatmap1, Heatmap heatmap2) {
252
+ expectHeatmapDataMoreOrLessEquals (heatmap1.data, heatmap2.data);
253
+ expectHeatmapGradientMoreOrLessEquals (heatmap1.gradient, heatmap2.gradient);
254
+
255
+ // Only Android supports `maxIntensity`
256
+ // so the platform value is undefined on others.
257
+ bool canHandleMaxIntensity () {
258
+ return Platform .isAndroid;
259
+ }
260
+
261
+ // Only iOS supports `minimumZoomIntensity` and `maximumZoomIntensity`
262
+ // so the platform value is undefined on others.
263
+ bool canHandleZoomIntensity () {
264
+ return Platform .isIOS;
265
+ }
266
+
267
+ if (canHandleMaxIntensity ()) {
268
+ expect (heatmap1.maxIntensity, heatmap2.maxIntensity);
269
+ }
270
+ expect (
271
+ heatmap1.opacity,
272
+ moreOrLessEquals (heatmap2.opacity, epsilon: floatTolerance),
273
+ );
274
+ expect (heatmap1.radius, heatmap2.radius);
275
+ if (canHandleZoomIntensity ()) {
276
+ expect (heatmap1.minimumZoomIntensity, heatmap2.minimumZoomIntensity);
277
+ expect (heatmap1.maximumZoomIntensity, heatmap2.maximumZoomIntensity);
278
+ }
279
+ }
280
+
281
+ const Heatmap heatmap1 = Heatmap (
282
+ heatmapId: HeatmapId ('heatmap_1' ),
283
+ data: < WeightedLatLng > [
284
+ WeightedLatLng (LatLng (37.782 , - 122.447 )),
285
+ WeightedLatLng (LatLng (37.782 , - 122.445 )),
286
+ WeightedLatLng (LatLng (37.782 , - 122.443 )),
287
+ WeightedLatLng (LatLng (37.782 , - 122.441 )),
288
+ WeightedLatLng (LatLng (37.782 , - 122.439 )),
289
+ WeightedLatLng (LatLng (37.782 , - 122.437 )),
290
+ WeightedLatLng (LatLng (37.782 , - 122.435 )),
291
+ WeightedLatLng (LatLng (37.785 , - 122.447 )),
292
+ WeightedLatLng (LatLng (37.785 , - 122.445 )),
293
+ WeightedLatLng (LatLng (37.785 , - 122.443 )),
294
+ WeightedLatLng (LatLng (37.785 , - 122.441 )),
295
+ WeightedLatLng (LatLng (37.785 , - 122.439 )),
296
+ WeightedLatLng (LatLng (37.785 , - 122.437 )),
297
+ WeightedLatLng (LatLng (37.785 , - 122.435 ), weight: 2 )
298
+ ],
299
+ dissipating: false ,
300
+ gradient: HeatmapGradient (
301
+ < HeatmapGradientColor > [
302
+ HeatmapGradientColor (
303
+ Color .fromARGB (255 , 0 , 255 , 255 ),
304
+ 0.2 ,
305
+ ),
306
+ HeatmapGradientColor (
307
+ Color .fromARGB (255 , 0 , 63 , 255 ),
308
+ 0.4 ,
309
+ ),
310
+ HeatmapGradientColor (
311
+ Color .fromARGB (255 , 0 , 0 , 191 ),
312
+ 0.6 ,
313
+ ),
314
+ HeatmapGradientColor (
315
+ Color .fromARGB (255 , 63 , 0 , 91 ),
316
+ 0.8 ,
317
+ ),
318
+ HeatmapGradientColor (
319
+ Color .fromARGB (255 , 255 , 0 , 0 ),
320
+ 1 ,
321
+ ),
322
+ ],
323
+ ),
324
+ maxIntensity: 1 ,
325
+ opacity: 0.5 ,
326
+ radius: HeatmapRadius .fromPixels (40 ),
327
+ minimumZoomIntensity: 1 ,
328
+ maximumZoomIntensity: 20 ,
329
+ );
330
+
331
+ testWidgets ('set heatmap correctly' , (WidgetTester tester) async {
332
+ final Completer <int > mapIdCompleter = Completer <int >();
333
+ final Heatmap heatmap2 = Heatmap (
334
+ heatmapId: const HeatmapId ('heatmap_2' ),
335
+ data: heatmap1.data,
336
+ dissipating: heatmap1.dissipating,
337
+ gradient: heatmap1.gradient,
338
+ maxIntensity: heatmap1.maxIntensity,
339
+ opacity: heatmap1.opacity - 0.1 ,
340
+ radius: heatmap1.radius,
341
+ minimumZoomIntensity: heatmap1.minimumZoomIntensity,
342
+ maximumZoomIntensity: heatmap1.maximumZoomIntensity,
343
+ );
344
+
345
+ await tester.pumpWidget (
346
+ Directionality (
347
+ textDirection: TextDirection .ltr,
348
+ child: GoogleMap (
349
+ initialCameraPosition: kInitialCameraPosition,
350
+ heatmaps: < Heatmap > {heatmap1, heatmap2},
351
+ onMapCreated: (GoogleMapController controller) {
352
+ mapIdCompleter.complete (controller.mapId);
353
+ },
354
+ ),
355
+ ),
356
+ );
357
+ await tester.pumpAndSettle (const Duration (seconds: 3 ));
358
+
359
+ final int mapId = await mapIdCompleter.future;
360
+ final GoogleMapsInspectorPlatform inspector =
361
+ GoogleMapsInspectorPlatform .instance! ;
362
+
363
+ if (inspector.supportsGettingHeatmapInfo ()) {
364
+ final Heatmap heatmapInfo1 =
365
+ (await inspector.getHeatmapInfo (heatmap1.mapsId, mapId: mapId))! ;
366
+ final Heatmap heatmapInfo2 =
367
+ (await inspector.getHeatmapInfo (heatmap2.mapsId, mapId: mapId))! ;
368
+
369
+ expectHeatmapEquals (heatmap1, heatmapInfo1);
370
+ expectHeatmapEquals (heatmap2, heatmapInfo2);
371
+ }
372
+ });
373
+
374
+ testWidgets ('update heatmaps correctly' , (WidgetTester tester) async {
375
+ final Completer <int > mapIdCompleter = Completer <int >();
376
+ final Key key = GlobalKey ();
377
+
378
+ await tester.pumpWidget (
379
+ Directionality (
380
+ textDirection: TextDirection .ltr,
381
+ child: GoogleMap (
382
+ key: key,
383
+ initialCameraPosition: kInitialCameraPosition,
384
+ heatmaps: < Heatmap > {heatmap1},
385
+ onMapCreated: (GoogleMapController controller) {
386
+ mapIdCompleter.complete (controller.mapId);
387
+ },
388
+ ),
389
+ ),
390
+ );
391
+
392
+ final int mapId = await mapIdCompleter.future;
393
+ final GoogleMapsInspectorPlatform inspector =
394
+ GoogleMapsInspectorPlatform .instance! ;
395
+
396
+ final Heatmap heatmap1New = heatmap1.copyWith (
397
+ dataParam: heatmap1.data.sublist (5 ),
398
+ dissipatingParam: ! heatmap1.dissipating,
399
+ gradientParam: heatmap1.gradient,
400
+ maxIntensityParam: heatmap1.maxIntensity! + 1 ,
401
+ opacityParam: heatmap1.opacity - 0.1 ,
402
+ radiusParam: HeatmapRadius .fromPixels (heatmap1.radius.radius + 1 ),
403
+ minimumZoomIntensityParam: heatmap1.minimumZoomIntensity + 1 ,
404
+ maximumZoomIntensityParam: heatmap1.maximumZoomIntensity + 1 ,
405
+ );
406
+
407
+ await tester.pumpWidget (
408
+ Directionality (
409
+ textDirection: TextDirection .ltr,
410
+ child: GoogleMap (
411
+ key: key,
412
+ initialCameraPosition: kInitialCameraPosition,
413
+ heatmaps: < Heatmap > {heatmap1New},
414
+ onMapCreated: (GoogleMapController controller) {
415
+ fail ('update: OnMapCreated should get called only once.' );
416
+ },
417
+ ),
418
+ ),
419
+ );
420
+
421
+ await tester.pumpAndSettle (const Duration (seconds: 3 ));
422
+
423
+ if (inspector.supportsGettingHeatmapInfo ()) {
424
+ final Heatmap heatmapInfo1 =
425
+ (await inspector.getHeatmapInfo (heatmap1.mapsId, mapId: mapId))! ;
426
+
427
+ expectHeatmapEquals (heatmap1New, heatmapInfo1);
428
+ }
429
+ });
430
+
431
+ testWidgets ('remove heatmaps correctly' , (WidgetTester tester) async {
432
+ final Completer <int > mapIdCompleter = Completer <int >();
433
+ final Key key = GlobalKey ();
434
+
435
+ await tester.pumpWidget (
436
+ Directionality (
437
+ textDirection: TextDirection .ltr,
438
+ child: GoogleMap (
439
+ key: key,
440
+ initialCameraPosition: kInitialCameraPosition,
441
+ heatmaps: < Heatmap > {heatmap1},
442
+ onMapCreated: (GoogleMapController controller) {
443
+ mapIdCompleter.complete (controller.mapId);
444
+ },
445
+ ),
446
+ ),
447
+ );
448
+
449
+ final int mapId = await mapIdCompleter.future;
450
+ final GoogleMapsInspectorPlatform inspector =
451
+ GoogleMapsInspectorPlatform .instance! ;
452
+
453
+ await tester.pumpWidget (
454
+ Directionality (
455
+ textDirection: TextDirection .ltr,
456
+ child: GoogleMap (
457
+ key: key,
458
+ initialCameraPosition: kInitialCameraPosition,
459
+ onMapCreated: (GoogleMapController controller) {
460
+ fail ('OnMapCreated should get called only once.' );
461
+ },
462
+ ),
463
+ ),
464
+ );
465
+
466
+ await tester.pumpAndSettle (const Duration (seconds: 3 ));
467
+
468
+ if (inspector.supportsGettingHeatmapInfo ()) {
469
+ final Heatmap ? heatmapInfo1 =
470
+ await inspector.getHeatmapInfo (heatmap1.mapsId, mapId: mapId);
471
+
472
+ expect (heatmapInfo1, isNull);
473
+ }
474
+ });
207
475
}
208
476
209
477
class _DebugTileProvider implements TileProvider {
0 commit comments