Skip to content

Commit 49c1f26

Browse files
authored
multi: add tests, remove flutter_markdown package (#133)
1 parent 97bee73 commit 49c1f26

File tree

14 files changed

+516
-32
lines changed

14 files changed

+516
-32
lines changed

example/integration_test/app.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ class App extends StatelessWidget {
1010
this.options,
1111
this.onMapCreated,
1212
this.onStyleLoaded,
13+
this.onEvent,
1314
super.key,
1415
});
1516

1617
final MapOptions? options;
1718
final MapCreatedCallback? onMapCreated;
19+
final MapEventCallback? onEvent;
1820
final VoidCallback? onStyleLoaded;
1921

2022
@override
@@ -26,6 +28,7 @@ class App extends StatelessWidget {
2628
options: options ?? MapOptions(initCenter: Position(0, 0)),
2729
onMapCreated: onMapCreated,
2830
onStyleLoaded: onStyleLoaded,
31+
onEvent: onEvent,
2932
),
3033
),
3134
);

example/integration_test/controller_test.dart

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
66
import 'package:flutter_test/flutter_test.dart';
77
import 'package:integration_test/integration_test.dart';
88
import 'package:maplibre/maplibre.dart';
9+
import 'package:maplibre_example/styled_map_page.dart';
910

1011
import 'app.dart';
1112

@@ -14,25 +15,33 @@ void main() {
1415
group('controller', () {
1516
testWidgets('getCamera', (tester) async {
1617
final ctrlCompleter = Completer<MapController>();
18+
final events = <MapEvent>[];
1719
final app = App(
1820
onMapCreated: ctrlCompleter.complete,
1921
options: MapOptions(initCenter: Position(1, 2)),
22+
onEvent: events.add,
2023
);
2124
await tester.pumpWidget(app);
2225
final ctrl = await ctrlCompleter.future;
26+
events.clear();
2327
await ctrl.moveCamera(
2428
center: Position(1, 1),
2529
bearing: 1,
2630
zoom: 1,
2731
pitch: 1,
2832
);
2933
await tester.pumpAndSettle();
34+
3035
final camera = ctrl.getCamera();
3136
expect(camera.center.lng, closeTo(1, 0.00001));
3237
expect(camera.center.lat, closeTo(1, 0.00001));
3338
expect(camera.zoom, closeTo(1, 0.00001));
3439
expect(camera.bearing, closeTo(1, 0.00001));
3540
expect(camera.pitch, closeTo(1, 0.00001));
41+
42+
expect(events[events.length - 3], isA<MapEventStartMoveCamera>());
43+
expect(events[events.length - 2], isA<MapEventMoveCamera>());
44+
expect(events[events.length - 1], isA<MapEventCameraIdle>());
3645
});
3746

3847
testWidgets('toScreenLocation', (tester) async {
@@ -49,6 +58,185 @@ void main() {
4958
expect(offset.dy, greaterThanOrEqualTo(0));
5059
});
5160

61+
testWidgets('toScreenLocations', (tester) async {
62+
final ctrlCompleter = Completer<MapController>();
63+
final app = App(
64+
onMapCreated: ctrlCompleter.complete,
65+
options: MapOptions(initCenter: Position(1, 2)),
66+
);
67+
await tester.pumpWidget(app);
68+
final ctrl = await ctrlCompleter.future;
69+
final offsets = await ctrl.toScreenLocations([
70+
Position(1, 2),
71+
Position(43.5, -23),
72+
]);
73+
// Different devices have different screen sizes.
74+
expect(offsets[0].dx, greaterThanOrEqualTo(0));
75+
expect(offsets[0].dy, greaterThanOrEqualTo(0));
76+
expect(offsets[1].dx, greaterThanOrEqualTo(0));
77+
expect(offsets[1].dy, greaterThanOrEqualTo(0));
78+
});
79+
80+
testWidgets('toLngLat', (tester) async {
81+
final ctrlCompleter = Completer<MapController>();
82+
final app = App(
83+
onMapCreated: ctrlCompleter.complete,
84+
options: MapOptions(initCenter: Position(1, 2)),
85+
);
86+
await tester.pumpWidget(app);
87+
final ctrl = await ctrlCompleter.future;
88+
final lngLat = await ctrl.toLngLat(Offset.zero);
89+
// Different devices have different screen sizes.
90+
expect(lngLat.lng, isNot(equals(0)));
91+
expect(lngLat.lat, isNot(equals(0)));
92+
});
93+
94+
testWidgets('toLnLats', (tester) async {
95+
final ctrlCompleter = Completer<MapController>();
96+
final app = App(
97+
onMapCreated: ctrlCompleter.complete,
98+
options: MapOptions(initCenter: Position(1, 2)),
99+
);
100+
await tester.pumpWidget(app);
101+
final ctrl = await ctrlCompleter.future;
102+
final lngLats = await ctrl.toLngLats([
103+
const Offset(23, 53),
104+
const Offset(23.3, 53.5),
105+
]);
106+
// Different devices have different screen sizes.
107+
expect(lngLats[0].lng, isNot(equals(0)));
108+
expect(lngLats[0].lat, isNot(equals(0)));
109+
expect(lngLats[1].lng, isNot(equals(0)));
110+
expect(lngLats[1].lat, isNot(equals(0)));
111+
});
112+
113+
testWidgets('getMetersPerPixelAtLatitude', (tester) async {
114+
final ctrlCompleter = Completer<MapController>();
115+
final app = App(
116+
onMapCreated: ctrlCompleter.complete,
117+
options: MapOptions(initCenter: Position(1, 2), initZoom: 10),
118+
);
119+
await tester.pumpWidget(app);
120+
final ctrl = await ctrlCompleter.future;
121+
final meters = await ctrl.getMetersPerPixelAtLatitude(2.34);
122+
expect(meters, closeTo(76.37, 0.1));
123+
});
124+
125+
testWidgets('getVisibleRegion', (tester) async {
126+
final ctrlCompleter = Completer<MapController>();
127+
final app = App(
128+
onMapCreated: ctrlCompleter.complete,
129+
options: MapOptions(initCenter: Position(0, 0), initZoom: 10),
130+
);
131+
await tester.pumpWidget(app);
132+
final ctrl = await ctrlCompleter.future;
133+
final region = await ctrl.getVisibleRegion();
134+
// testing devices have different screen sizes
135+
expect(region.longitudeWest, lessThan(0));
136+
expect(region.longitudeEast, greaterThan(0));
137+
expect(region.latitudeNorth, greaterThan(0));
138+
expect(region.latitudeSouth, lessThan(0));
139+
140+
expect(region.longitudeWest, greaterThan(-10));
141+
expect(region.longitudeEast, lessThan(10));
142+
expect(region.latitudeNorth, lessThan(10));
143+
expect(region.latitudeSouth, greaterThan(-10));
144+
});
145+
146+
testWidgets('removeLayer', (tester) async {
147+
final ctrlCompleter = Completer<MapController>();
148+
final app = App(
149+
onMapCreated: ctrlCompleter.complete,
150+
options: MapOptions(initCenter: Position(0, 0), initZoom: 10),
151+
);
152+
await tester.pumpWidget(app);
153+
final ctrl = await ctrlCompleter.future;
154+
// ensure no crash if a layer does not exist
155+
await ctrl.removeLayer('notExisting');
156+
157+
const layer = RasterLayer(id: 'rasterLayer', sourceId: 'source');
158+
await ctrl.addLayer(layer);
159+
await ctrl.removeLayer(layer.id);
160+
});
161+
162+
testWidgets('removeSource', (tester) async {
163+
final ctrlCompleter = Completer<MapController>();
164+
final app = App(
165+
onMapCreated: ctrlCompleter.complete,
166+
options: MapOptions(initCenter: Position(0, 0), initZoom: 10),
167+
);
168+
await tester.pumpWidget(app);
169+
final ctrl = await ctrlCompleter.future;
170+
171+
// ensure no crash if a source does not exist
172+
await ctrl.removeSource('notExisting');
173+
174+
const source = GeoJsonSource(id: 'source', data: '{}');
175+
await ctrl.addSource(source);
176+
await ctrl.removeSource(source.id);
177+
});
178+
179+
testWidgets('updateGeoJsonSource', (tester) async {
180+
final ctrlCompleter = Completer<MapController>();
181+
final app = App(
182+
onMapCreated: ctrlCompleter.complete,
183+
options: MapOptions(initCenter: Position(0, 0), initZoom: 10),
184+
);
185+
await tester.pumpWidget(app);
186+
final ctrl = await ctrlCompleter.future;
187+
188+
const source = GeoJsonSource(id: '1', data: '{}');
189+
await ctrl.addSource(source);
190+
await ctrl.updateGeoJsonSource(
191+
id: source.id,
192+
data: jsonEncode(
193+
GeometryCollection(geometries: [Point(coordinates: Position(0, 0))])
194+
.toJson(),
195+
),
196+
);
197+
});
198+
199+
testWidgets('queryLayers', (tester) async {
200+
final ctrlCompleter = Completer<MapController>();
201+
final styleCompleter = Completer<void>();
202+
final app = App(
203+
onMapCreated: ctrlCompleter.complete,
204+
onStyleLoaded: styleCompleter.complete,
205+
options: MapOptions(initCenter: Position(0, 0), initZoom: 10),
206+
);
207+
await tester.pumpWidget(app);
208+
final ctrl = await ctrlCompleter.future;
209+
await styleCompleter.future;
210+
final size = tester.getSize(find.byType(MapLibreMap));
211+
212+
var layers = await ctrl.queryLayers(Offset(size.width, size.height));
213+
expect(layers, hasLength(0));
214+
215+
layers = await ctrl.queryLayers(Offset.zero);
216+
expect(layers, hasLength(0));
217+
});
218+
219+
testWidgets('getAttributions', (tester) async {
220+
final ctrlCompleter = Completer<MapController>();
221+
final styleCompleter = Completer<void>();
222+
final app = App(
223+
onMapCreated: ctrlCompleter.complete,
224+
onStyleLoaded: styleCompleter.complete,
225+
options: MapOptions(
226+
initCenter: Position(0, 0),
227+
initZoom: 10,
228+
initStyle: StyledMapPage.styleUrl,
229+
),
230+
);
231+
await tester.pumpWidget(app);
232+
final ctrl = await ctrlCompleter.future;
233+
await styleCompleter.future;
234+
235+
final attributions = await ctrl.getAttributions();
236+
expect(attributions, hasLength(1));
237+
expect(attributions.first, contains('OpenStreetMap'));
238+
});
239+
52240
testWidgets('moveCamera', (tester) async {
53241
final ctrlCompleter = Completer<MapController>();
54242
final app = App(onMapCreated: ctrlCompleter.complete);
@@ -172,4 +360,85 @@ void main() {
172360
await ctrl.addLayer(layer);
173361
await tester.pumpAndSettle();
174362
});
363+
testWidgets('add FillLayer', (tester) async {
364+
final ctrlCompleter = Completer<MapController>();
365+
final app = App(onMapCreated: ctrlCompleter.complete);
366+
await tester.pumpWidget(app);
367+
final ctrl = await ctrlCompleter.future;
368+
const layer = FillLayer(id: '1', sourceId: 'source1');
369+
await ctrl.addLayer(layer);
370+
await tester.pumpAndSettle();
371+
});
372+
testWidgets('add CircleLayer', (tester) async {
373+
final ctrlCompleter = Completer<MapController>();
374+
final app = App(onMapCreated: ctrlCompleter.complete);
375+
await tester.pumpWidget(app);
376+
final ctrl = await ctrlCompleter.future;
377+
const layer = CircleLayer(id: '1', sourceId: 'source1');
378+
await ctrl.addLayer(layer);
379+
await tester.pumpAndSettle();
380+
});
381+
testWidgets('add FillExtrusionLayer', (tester) async {
382+
final ctrlCompleter = Completer<MapController>();
383+
final app = App(onMapCreated: ctrlCompleter.complete);
384+
await tester.pumpWidget(app);
385+
final ctrl = await ctrlCompleter.future;
386+
const layer = FillExtrusionLayer(id: '1', sourceId: 'source1');
387+
await ctrl.addLayer(layer);
388+
await tester.pumpAndSettle();
389+
});
390+
testWidgets('add HeatmapLayer', (tester) async {
391+
final ctrlCompleter = Completer<MapController>();
392+
final app = App(onMapCreated: ctrlCompleter.complete);
393+
await tester.pumpWidget(app);
394+
final ctrl = await ctrlCompleter.future;
395+
const layer = HeatmapLayer(id: '1', sourceId: 'source1');
396+
await ctrl.addLayer(layer);
397+
await tester.pumpAndSettle();
398+
});
399+
testWidgets('add HillshadeLayer', (tester) async {
400+
final ctrlCompleter = Completer<MapController>();
401+
final app = App(onMapCreated: ctrlCompleter.complete);
402+
await tester.pumpWidget(app);
403+
final ctrl = await ctrlCompleter.future;
404+
const layer = HillshadeLayer(id: '1', sourceId: 'source1');
405+
await ctrl.addLayer(layer);
406+
await tester.pumpAndSettle();
407+
});
408+
testWidgets('add LineLayer', (tester) async {
409+
final ctrlCompleter = Completer<MapController>();
410+
final app = App(onMapCreated: ctrlCompleter.complete);
411+
await tester.pumpWidget(app);
412+
final ctrl = await ctrlCompleter.future;
413+
const layer = LineLayer(id: '1', sourceId: 'source1');
414+
await ctrl.addLayer(layer);
415+
await tester.pumpAndSettle();
416+
});
417+
testWidgets('add RasterLayer', (tester) async {
418+
final ctrlCompleter = Completer<MapController>();
419+
final app = App(onMapCreated: ctrlCompleter.complete);
420+
await tester.pumpWidget(app);
421+
final ctrl = await ctrlCompleter.future;
422+
const layer = RasterLayer(id: '1', sourceId: 'source1');
423+
await ctrl.addLayer(layer);
424+
await tester.pumpAndSettle();
425+
});
426+
testWidgets('add SymbolLayer', (tester) async {
427+
final ctrlCompleter = Completer<MapController>();
428+
final app = App(onMapCreated: ctrlCompleter.complete);
429+
await tester.pumpWidget(app);
430+
final ctrl = await ctrlCompleter.future;
431+
const layer = SymbolLayer(id: '1', sourceId: 'source1');
432+
await ctrl.addLayer(layer);
433+
await tester.pumpAndSettle();
434+
});
435+
testWidgets('add unknown Layer', (tester) async {
436+
final ctrlCompleter = Completer<MapController>();
437+
final app = App(onMapCreated: ctrlCompleter.complete);
438+
await tester.pumpWidget(app);
439+
final ctrl = await ctrlCompleter.future;
440+
const layer = SymbolLayer(id: '1', sourceId: 'source1');
441+
await ctrl.addLayer(layer);
442+
await tester.pumpAndSettle();
443+
});
175444
}

example/integration_test/general_test.dart

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,15 @@ void main() {
5353
});
5454

5555
testWidgets('update map options', (tester) async {
56-
await tester.pumpWidget(
57-
App(
58-
options: MapOptions(
59-
initCenter: Position(0, 0),
60-
),
61-
),
62-
);
56+
final o1 = MapOptions(initCenter: Position(0, 0));
57+
await tester.pumpWidget(App(options: o1));
6358
await tester.pumpAndSettle();
6459
await tester.pump();
65-
// TODO: better checks
6660
expect(tester.allWidgets.any((w) => w is MapLibreMap), isTrue);
61+
62+
final o2 = MapOptions(initCenter: Position(0, 0), maxPitch: 0);
63+
await tester.pumpWidget(App(options: o2));
64+
await tester.pump();
6765
});
6866
});
6967
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import 'package:maplibre/maplibre.dart';
2+
import 'package:mocktail/mocktail.dart';
3+
4+
class MockLayer extends Mock implements Layer {}

example/integration_test/offline_manager_test.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ void main() {
5656
manager.runPackDatabaseAutomatically(enabled: true);
5757
manager.dispose();
5858
});
59+
testWidgets('getOfflineRegion', (tester) async {
60+
await tester.pumpWidget(const App());
61+
await tester.pumpAndSettle();
62+
final manager = await OfflineManager.createInstance();
63+
expect(
64+
() async => manager.getOfflineRegion(regionId: 234),
65+
throwsA(isA<Exception>()),
66+
);
67+
manager.dispose();
68+
});
69+
testWidgets('listOfflineRegions', (tester) async {
70+
await tester.pumpWidget(const App());
71+
await tester.pumpAndSettle();
72+
final manager = await OfflineManager.createInstance();
73+
expect(
74+
await manager.listOfflineRegions(),
75+
isEmpty,
76+
);
77+
manager.dispose();
78+
});
5979
/*testWidgets('downloadRegion', (tester) async {
6080
await tester.pumpWidget(const App());
6181
await tester.pumpAndSettle();

example/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ dev_dependencies:
2222
sdk: flutter
2323
integration_test:
2424
sdk: flutter
25+
mocktail: ^1.0.4
2526
very_good_analysis: ^6.0.0
2627

2728
flutter:

0 commit comments

Comments
 (0)