Skip to content

Commit

Permalink
[google_maps_flutter_ios] Add native tests for clustering
Browse files Browse the repository at this point in the history
  • Loading branch information
jokerttu committed Apr 3, 2024
1 parent d45fd74 commit b0e9ada
Show file tree
Hide file tree
Showing 4 changed files with 253 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
4510D964F3B1259FEDD3ABA6 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */; };
524C1BBF2BBD60A4009D3ABB /* FLTClusterManagersControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 524C1BBE2BBD60A4009D3ABB /* FLTClusterManagersControllerTests.m */; };
6851F3562835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6851F3552835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m */; };
68E4726A2836FF0C00BDDDAC /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 68E472692836FF0C00BDDDAC /* MapKit.framework */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
Expand Down Expand Up @@ -59,6 +60,7 @@
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
524C1BBE2BBD60A4009D3ABB /* FLTClusterManagersControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FLTClusterManagersControllerTests.m; sourceTree = "<group>"; };
6851F3552835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLTGoogleMapJSONConversionsConversionTests.m; sourceTree = "<group>"; };
68E472692836FF0C00BDDDAC /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk/System/iOSSupport/System/Library/Frameworks/MapKit.framework; sourceTree = DEVELOPER_DIR; };
733AFAB37683A9DA7512F09C /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -200,6 +202,7 @@
children = (
6851F3552835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m */,
F7151F12265D7ED70028CB91 /* GoogleMapsTests.m */,
524C1BBE2BBD60A4009D3ABB /* FLTClusterManagersControllerTests.m */,
982F2A6A27BADE17003C81F4 /* PartiallyMockedMapView.h */,
982F2A6B27BADE17003C81F4 /* PartiallyMockedMapView.m */,
F7151F14265D7ED70028CB91 /* Info.plist */,
Expand Down Expand Up @@ -464,6 +467,7 @@
6851F3562835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m in Sources */,
982F2A6C27BADE17003C81F4 /* PartiallyMockedMapView.m in Sources */,
0DD7B6C32B744EEF00E857FD /* FLTTileProviderControllerTests.m in Sources */,
524C1BBF2BBD60A4009D3ABB /* FLTClusterManagersControllerTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// 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 google_maps_flutter_ios;
@import google_maps_flutter_ios.Test;
@import XCTest;
@import GoogleMaps;

#import <Flutter/Flutter.h>
#import <OCMock/OCMock.h>
#import "PartiallyMockedMapView.h"

@interface FLTGoogleMapFactory (Test)
@property(strong, nonatomic, readonly) id<NSObject> sharedMapServices;
@end

@interface FLTClusterManagersControllerTests : XCTestCase
@end

@implementation FLTClusterManagersControllerTests

- (void)testClustering {
NSObject<FlutterPluginRegistrar> *registrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar));
CGRect frame = CGRectMake(0, 0, 100, 100);
PartiallyMockedMapView *mapView = [[PartiallyMockedMapView alloc]
initWithFrame:frame
camera:[[GMSCameraPosition alloc] initWithLatitude:0 longitude:0 zoom:0]];

NSString *channelName = [NSString stringWithFormat:@"plugins.flutter.dev/google_maps_ios_%d", 0];
FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:channelName
binaryMessenger:registrar.messenger];

NSString *clusterManagerId = @"cm1";

FLTClusterManagersController *clusterManagersController =
[[FLTClusterManagersController alloc] initWithMethodChannel:channel mapView:mapView];
FLTMarkersController *markersController =
[[FLTMarkersController alloc] initWithClusterManagersController:clusterManagersController
channel:channel
mapView:mapView
registrar:registrar];

// Add cluster manager
NSDictionary *clusterManagerToAdd = @{@"clusterManagerId" : clusterManagerId};
[clusterManagersController addClusterManagers:@[ clusterManagerToAdd ]];

// Verify that cluster manager is available
GMUClusterManager *clusterManager =
[clusterManagersController clusterManagerWithIdentifier:clusterManagerId];
XCTAssertNotNil(clusterManager, @"Cluster Manager should not be nil");

// Add markers
NSString *markerId1 = @"m1";
NSString *markerId2 = @"m2";

NSDictionary *marker1 =
@{@"markerId" : markerId1, @"position" : @[ @0, @0 ], @"clusterManagerId" : clusterManagerId};
NSDictionary *marker2 =
@{@"markerId" : markerId2, @"position" : @[ @0, @0 ], @"clusterManagerId" : clusterManagerId};
[markersController addMarkers:@[ marker1, marker2 ]];

// Invoke clustering
[clusterManagersController invokeClusteringForEachClusterManager];

// Verify that the markers were added to the cluster manager
FlutterResult resultObject1 = ^(id _Nullable result) {
NSArray *clusters = (NSArray *)result;
for (NSDictionary *cluster in clusters) {
NSString *cmId = cluster[@"clusterManagerId"];
XCTAssertNotNil(cmId, @"Cluster Manager Identifier should not be nil");
if ([cmId isEqualToString:clusterManagerId]) {
NSArray *markerIds = cluster[@"markerIds"];
XCTAssertEqual(markerIds.count, 2, @"Cluster should contain two marker");
XCTAssertTrue([markerIds containsObject:markerId1], @"Cluster should contain markerId1");
XCTAssertTrue([markerIds containsObject:markerId2], @"Cluster should contain markerId2");
return;
}
}
// Cluster for clustermanager not found, fail the test
XCTFail(@"Cluster manager not found");
};
[clusterManagersController serializeClustersWithIdentifier:clusterManagerId result:resultObject1];

[markersController removeMarkersWithIdentifiers:@[ markerId2 ]];

// Verify that the marker2 is removed from the clusterManager
FlutterResult resultObject2 = ^(id _Nullable result) {
NSArray *clusters = (NSArray *)result;
for (NSDictionary *cluster in clusters) {
NSString *cmId = cluster[@"clusterManagerId"];
XCTAssertNotNil(cmId, @"Cluster Manager ID should not be nil");
if ([cmId isEqualToString:clusterManagerId]) {
NSArray *markerIds = cluster[@"markerIds"];
XCTAssertEqual(markerIds.count, 1, @"Cluster should contain one marker");
XCTAssertTrue([markerIds containsObject:markerId1], @"Cluster should contain markerId1");
return;
}
}
// Cluster for clustermanager not found, fail the test
XCTFail(@"Cluster manager not found");
};
[clusterManagersController serializeClustersWithIdentifier:clusterManagerId result:resultObject2];

[markersController removeMarkersWithIdentifiers:@[ markerId1 ]];

// Verify that all markers are removed from clusterManager
FlutterResult resultObject3 = ^(id _Nullable result) {
NSArray *clusters = (NSArray *)result;
XCTAssertEqual(clusters.count, 0, @"Cluster Manager should not contain any clusters");
};
[clusterManagersController serializeClustersWithIdentifier:clusterManagerId result:resultObject3];

// Remove cluster manager
[clusterManagersController removeClusterManagersWithIdentifiers:@[ clusterManagerId ]];

// Verify that the cluster manager is removed
clusterManager = [clusterManagersController clusterManagerWithIdentifier:clusterManagerId];
XCTAssertNil(clusterManager, @"Cluster Manager should be nil");
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
4510D964F3B1259FEDD3ABA6 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */; };
5299F3672BBD7955002AF906 /* FLTClusterManagersControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5299F3662BBD7955002AF906 /* FLTClusterManagersControllerTests.m */; };
68E4726A2836FF0C00BDDDAC /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 68E472692836FF0C00BDDDAC /* MapKit.framework */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
Expand Down Expand Up @@ -49,6 +50,7 @@
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
5299F3662BBD7955002AF906 /* FLTClusterManagersControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLTClusterManagersControllerTests.m; sourceTree = "<group>"; };
68E472692836FF0C00BDDDAC /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk/System/iOSSupport/System/Library/Frameworks/MapKit.framework; sourceTree = DEVELOPER_DIR; };
733AFAB37683A9DA7512F09C /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -176,6 +178,7 @@
F7151F11265D7ED70028CB91 /* RunnerTests */ = {
isa = PBXGroup;
children = (
5299F3662BBD7955002AF906 /* FLTClusterManagersControllerTests.m */,
F269303A2BB389BF00BF17C4 /* assets */,
F7151F12265D7ED70028CB91 /* GoogleMapsTests.m */,
982F2A6A27BADE17003C81F4 /* PartiallyMockedMapView.h */,
Expand Down Expand Up @@ -401,6 +404,7 @@
files = (
F7151F13265D7ED70028CB91 /* GoogleMapsTests.m in Sources */,
982F2A6C27BADE17003C81F4 /* PartiallyMockedMapView.m in Sources */,
5299F3672BBD7955002AF906 /* FLTClusterManagersControllerTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// 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 google_maps_flutter_ios;
@import google_maps_flutter_ios.Test;
@import XCTest;
@import GoogleMaps;

#import <Flutter/Flutter.h>
#import <OCMock/OCMock.h>
#import "PartiallyMockedMapView.h"

@interface FLTGoogleMapFactory (Test)
@property(strong, nonatomic, readonly) id<NSObject> sharedMapServices;
@end

@interface FLTClusterManagersControllerTests : XCTestCase
@end

@implementation FLTClusterManagersControllerTests

- (void)testClustering {
NSObject<FlutterPluginRegistrar> *registrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar));
CGRect frame = CGRectMake(0, 0, 100, 100);

PartiallyMockedMapView *mapView = [[PartiallyMockedMapView alloc]
initWithFrame:frame
camera:[[GMSCameraPosition alloc] initWithLatitude:0 longitude:0 zoom:0]];

NSString *channelName = [NSString stringWithFormat:@"plugins.flutter.dev/google_maps_ios_%d", 0];
FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:channelName
binaryMessenger:registrar.messenger];

NSString *clusterManagerId = @"cm1";

FLTClusterManagersController *clusterManagersController =
[[FLTClusterManagersController alloc] initWithMethodChannel:channel mapView:mapView];
FLTMarkersController *markersController =
[[FLTMarkersController alloc] initWithClusterManagersController:clusterManagersController
channel:channel
mapView:mapView
registrar:registrar];

// Add cluster manager
NSDictionary *clusterManagerToAdd = @{@"clusterManagerId" : clusterManagerId};
[clusterManagersController addClusterManagers:@[ clusterManagerToAdd ]];

// Verify that cluster manager is available
GMUClusterManager *clusterManager =
[clusterManagersController clusterManagerWithIdentifier:clusterManagerId];
XCTAssertNotNil(clusterManager, @"Cluster Manager should not be nil");

// Add markers
NSString *markerId1 = @"m1";
NSString *markerId2 = @"m2";

NSDictionary *marker1 =
@{@"markerId" : markerId1, @"position" : @[ @0, @0 ], @"clusterManagerId" : clusterManagerId};
NSDictionary *marker2 =
@{@"markerId" : markerId2, @"position" : @[ @0, @0 ], @"clusterManagerId" : clusterManagerId};
[markersController addMarkers:@[ marker1, marker2 ]];

// Invoke clustering
[clusterManagersController invokeClusteringForEachClusterManager];

// Verify that the markers were added to the cluster manager
FlutterResult resultObject1 = ^(id _Nullable result) {
NSArray *clusters = (NSArray *)result;
for (NSDictionary *cluster in clusters) {
NSString *cmId = cluster[@"clusterManagerId"];
XCTAssertNotNil(cmId, @"Cluster Manager Identifier should not be nil");
if ([cmId isEqualToString:clusterManagerId]) {
NSArray *markerIds = cluster[@"markerIds"];
XCTAssertEqual(markerIds.count, 2, @"Cluster should contain two marker");
XCTAssertTrue([markerIds containsObject:markerId1], @"Cluster should contain markerId1");
XCTAssertTrue([markerIds containsObject:markerId2], @"Cluster should contain markerId2");
return;
}
}
// Cluster for clustermanager not found, fail the test
XCTFail(@"Cluster manager not found");
};
[clusterManagersController serializeClustersWithIdentifier:clusterManagerId result:resultObject1];

[markersController removeMarkersWithIdentifiers:@[ markerId2 ]];

// Verify that the marker2 is removed from the clusterManager
FlutterResult resultObject2 = ^(id _Nullable result) {
NSArray *clusters = (NSArray *)result;
for (NSDictionary *cluster in clusters) {
NSString *cmId = cluster[@"clusterManagerId"];
XCTAssertNotNil(cmId, @"Cluster Manager ID should not be nil");
if ([cmId isEqualToString:clusterManagerId]) {
NSArray *markerIds = cluster[@"markerIds"];
XCTAssertEqual(markerIds.count, 1, @"Cluster should contain one marker");
XCTAssertTrue([markerIds containsObject:markerId1], @"Cluster should contain markerId1");
return;
}
}
// Cluster for clustermanager not found, fail the test
XCTFail(@"Cluster manager not found");
};
[clusterManagersController serializeClustersWithIdentifier:clusterManagerId result:resultObject2];

[markersController removeMarkersWithIdentifiers:@[ markerId1 ]];

// Verify that all markers are removed from clusterManager
FlutterResult resultObject3 = ^(id _Nullable result) {
NSArray *clusters = (NSArray *)result;
XCTAssertEqual(clusters.count, 0, @"Cluster Manager should not contain any clusters");
};
[clusterManagersController serializeClustersWithIdentifier:clusterManagerId result:resultObject3];

// Remove cluster manager
[clusterManagersController removeClusterManagersWithIdentifiers:@[ clusterManagerId ]];

// Verify that the cluster manager is removed
clusterManager = [clusterManagersController clusterManagerWithIdentifier:clusterManagerId];
XCTAssertNil(clusterManager, @"Cluster Manager should be nil");
}

@end

0 comments on commit b0e9ada

Please sign in to comment.