Add test cases for application life cycle

PiperOrigin-RevId: 828119642
This commit is contained in:
Guogang Li
2025-11-04 13:49:48 -08:00
committed by Copybara-Service
parent 58aa89ae00
commit 2c6c0a2524
4 changed files with 222 additions and 0 deletions
@@ -94,6 +94,36 @@ objc_library(
],
)
objc_library(
name = "AppLifecycleMonitorTestLibrary",
testonly = True,
srcs = [
"GNCFakeNotificationCenter.m",
"app_lifecycle_monitor_test.mm",
],
hdrs = [
"GNCFakeNotificationCenter.h",
],
deps = [
":PlatformTestsLibrary",
"//internal/platform/implementation:comm",
"//internal/platform/implementation/apple:GNCNotificationCenter",
"//internal/platform/implementation/apple:app_lifecycle_monitor",
"//third_party/apple_frameworks:UIKit",
"//third_party/apple_frameworks:XCTest",
"@com_google_googletest//:gtest",
],
)
ios_unit_test(
name = "AppLifecycleMonitorTest",
minimum_os_version = IOS_MINIMUM_OS,
runner = IOS_LATEST_TEST_RUNNER,
deps = [
":AppLifecycleMonitorTestLibrary",
],
)
ios_unit_test(
name = "PlatformTest",
minimum_os_version = IOS_MINIMUM_OS,
@@ -0,0 +1,24 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#import <Foundation/Foundation.h>
#import "internal/platform/implementation/apple/GNCNotificationCenter.h"
NS_ASSUME_NONNULL_BEGIN
@interface GNCFakeNotificationCenter : NSObject <GNCNotificationCenter>
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,67 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#import "internal/platform/implementation/apple/Tests/GNCFakeNotificationCenter.h"
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface GNCFakeNotificationObserver : NSObject
@property(nonatomic, copy) NSNotificationName name;
@property(nonatomic, copy) void (^block)(NSNotification *);
@end
@implementation GNCFakeNotificationObserver
@end
@implementation GNCFakeNotificationCenter {
NSMutableArray<GNCFakeNotificationObserver *> *_observers;
}
- (instancetype)init {
self = [super init];
if (self) {
_observers = [NSMutableArray array];
}
return self;
}
- (id<NSObject>)addObserverForName:(NSNotificationName)name
object:(nullable id)obj
queue:(nullable NSOperationQueue *)queue
usingBlock:(void (^)(NSNotification *notification))block {
GNCFakeNotificationObserver *observer = [[GNCFakeNotificationObserver alloc] init];
observer.name = name;
observer.block = block;
[_observers addObject:observer];
return observer;
}
- (void)removeObserver:(id)observer {
[_observers removeObject:observer];
}
- (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject {
NSNotification *notification = [NSNotification notificationWithName:aName object:anObject];
for (GNCFakeNotificationObserver *observer in [_observers copy]) {
if ([observer.name isEqualToString:aName]) {
observer.block(notification);
}
}
}
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,101 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#import "internal/platform/implementation/apple/app_lifecycle_monitor.h"
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#endif // TARGET_OS_IPHONE
#import <XCTest/XCTest.h>
#include <memory>
#import "internal/platform/implementation/apple/Tests/GNCFakeNotificationCenter.h"
#include "internal/platform/implementation/app_lifecycle_monitor.h"
using nearby::api::AppLifecycleMonitor;
@interface AppLifecycleMonitorTests : XCTestCase
@end
@implementation AppLifecycleMonitorTests {
GNCFakeNotificationCenter *_notificationCenter;
AppLifecycleMonitor::AppLifecycleState _appLifecycleState;
int _callbackCount;
std::unique_ptr<nearby::apple::AppLifecycleMonitor> _monitor;
}
- (void)setUp {
[super setUp];
_notificationCenter = [[GNCFakeNotificationCenter alloc] init];
_appLifecycleState = AppLifecycleMonitor::AppLifecycleState::kInactive;
_monitor = std::make_unique<nearby::apple::AppLifecycleMonitor>(
_notificationCenter, ^(AppLifecycleMonitor::AppLifecycleState state) {
_appLifecycleState = state;
_callbackCount++;
});
}
- (void)tearDown {
_monitor.reset();
[super tearDown];
}
- (void)testAppEntersBackground {
[_notificationCenter postNotificationName:UIApplicationDidEnterBackgroundNotification object:nil];
XCTAssertEqual(_appLifecycleState, AppLifecycleMonitor::AppLifecycleState::kBackground);
XCTAssertEqual(_callbackCount, 1);
}
- (void)testAppBecomesInactive {
[_notificationCenter postNotificationName:UIApplicationWillResignActiveNotification object:nil];
XCTAssertEqual(_appLifecycleState, AppLifecycleMonitor::AppLifecycleState::kInactive);
XCTAssertEqual(_callbackCount, 1);
}
- (void)testAppBecomesActive {
[_notificationCenter postNotificationName:UIApplicationDidBecomeActiveNotification object:nil];
XCTAssertEqual(_appLifecycleState, AppLifecycleMonitor::AppLifecycleState::kActive);
XCTAssertEqual(_callbackCount, 1);
}
- (void)testAppReceivesMultipleNotifications {
[_notificationCenter postNotificationName:UIApplicationWillResignActiveNotification object:nil];
XCTAssertEqual(_appLifecycleState, AppLifecycleMonitor::AppLifecycleState::kInactive);
XCTAssertEqual(_callbackCount, 1);
[_notificationCenter postNotificationName:UIApplicationDidEnterBackgroundNotification object:nil];
XCTAssertEqual(_appLifecycleState, AppLifecycleMonitor::AppLifecycleState::kBackground);
XCTAssertEqual(_callbackCount, 2);
[_notificationCenter postNotificationName:UIApplicationDidBecomeActiveNotification object:nil];
XCTAssertEqual(_appLifecycleState, AppLifecycleMonitor::AppLifecycleState::kActive);
XCTAssertEqual(_callbackCount, 3);
}
- (void)testNoCallbackAfterMonitorDestroyed {
// Destroy monitor and verify no callbacks are received.
_monitor.reset();
[_notificationCenter postNotificationName:UIApplicationDidBecomeActiveNotification object:nil];
XCTAssertEqual(_appLifecycleState, AppLifecycleMonitor::AppLifecycleState::kInactive);
XCTAssertEqual(_callbackCount, 0);
}
@end