mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
[NC Apple coverage] Refactor: Wrap Network.framework C functions for testability. Part I.
PiperOrigin-RevId: 828308553
This commit is contained in:
committed by
Copybara-Service
parent
d71b88c3a6
commit
cee0b3815e
@@ -26,6 +26,8 @@ objc_library(
|
||||
name = "WiFiCommon",
|
||||
srcs = [
|
||||
"GNCIPv4Address.m",
|
||||
"GNCNWBrowseResultImpl.m",
|
||||
"GNCNWBrowserImpl.m",
|
||||
"GNCNWConnectionImpl.m",
|
||||
"GNCNWFramework.m",
|
||||
"GNCNWFrameworkError.m",
|
||||
@@ -36,6 +38,10 @@ objc_library(
|
||||
],
|
||||
hdrs = [
|
||||
"GNCIPv4Address.h",
|
||||
"GNCNWBrowseResult.h",
|
||||
"GNCNWBrowseResultImpl.h",
|
||||
"GNCNWBrowser.h",
|
||||
"GNCNWBrowserImpl.h",
|
||||
"GNCNWConnection.h",
|
||||
"GNCNWConnectionImpl.h",
|
||||
"GNCNWFramework.h",
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
// 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 <Network/Network.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* A protocol to wrap Network.framework C functions to allow for faking in tests.
|
||||
*/
|
||||
@protocol GNCNWBrowseResult <NSObject>
|
||||
|
||||
/**
|
||||
* Enumerates the interfaces associated with a browse result.
|
||||
*
|
||||
* @param browseResult The browse result to enumerate.
|
||||
* @param block The block to apply to each interface.
|
||||
*/
|
||||
- (void)enumerateInterfaces:(nw_browse_result_t)browseResult
|
||||
usingBlock:(nw_browse_result_enumerate_interface_t)block;
|
||||
|
||||
/**
|
||||
* Returns the type of an interface, such as Wi-Fi or cellular.
|
||||
*
|
||||
* @param interface The interface to get the type of.
|
||||
* @return The type of the interface.
|
||||
*/
|
||||
- (nw_interface_type_t)interfaceGetType:(nw_interface_t)interface;
|
||||
|
||||
/**
|
||||
* Copies the TXT record associated with a browse result.
|
||||
*
|
||||
* @param browseResult The browse result to copy the TXT record from.
|
||||
* @return The TXT record object, or nil if one doesn't exist.
|
||||
*/
|
||||
- (nullable nw_txt_record_t)copyTXTRecordObject:(nw_browse_result_t)browseResult;
|
||||
|
||||
/**
|
||||
* Allows you to inspect the keys and values in a TXT record.
|
||||
*
|
||||
* @param txtRecord The TXT record to apply the block to.
|
||||
* @param block The block to apply to each key-value pair in the TXT record.
|
||||
*/
|
||||
- (void)applyTXTRecord:(nw_txt_record_t)txtRecord block:(nw_txt_record_applier_t)block;
|
||||
|
||||
/**
|
||||
* Compares two browse results to determine if they refer to the same endpoint and if any specific
|
||||
* attributes of the endpoint have changed.
|
||||
*
|
||||
* @param oldResult The older browse result.
|
||||
* @param newResult The newer browse result.
|
||||
* @return The changes between the two browse results.
|
||||
*/
|
||||
- (nw_browse_result_change_t)getChangesFrom:(nw_browse_result_t)oldResult
|
||||
to:(nw_browse_result_t)newResult;
|
||||
|
||||
/**
|
||||
* Gets the endpoint associated with a browse result.
|
||||
*
|
||||
* @param result The browse result to get the endpoint from.
|
||||
* @return The endpoint associated with the browse result, or nil if one doesn't exist.
|
||||
*/
|
||||
- (nullable nw_endpoint_t)copyEndpointFromResult:(nw_browse_result_t)result;
|
||||
|
||||
/**
|
||||
* Returns the service name if the endpoint is a Bonjour service endpoint.
|
||||
*
|
||||
* @param endpoint The endpoint to get the Bonjour service name from.
|
||||
* @return The Bonjour service name, or nil if the endpoint is not a Bonjour service endpoint.
|
||||
*/
|
||||
- (nullable NSString *)getBonjourServiceNameFromEndpoint:(nw_endpoint_t)endpoint;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -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 "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWBrowseResult.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface GNCNWBrowseResultImpl : NSObject <GNCNWBrowseResult>
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,56 @@
|
||||
// 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/Mediums/WiFiCommon/GNCNWBrowseResultImpl.h"
|
||||
|
||||
#import <Network/Network.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation GNCNWBrowseResultImpl
|
||||
|
||||
- (void)enumerateInterfaces:(nw_browse_result_t)browseResult
|
||||
usingBlock:(nw_browse_result_enumerate_interface_t)block {
|
||||
nw_browse_result_enumerate_interfaces(browseResult, block);
|
||||
}
|
||||
|
||||
- (nw_interface_type_t)interfaceGetType:(nw_interface_t)interface {
|
||||
return nw_interface_get_type(interface);
|
||||
}
|
||||
|
||||
- (nullable nw_txt_record_t)copyTXTRecordObject:(nw_browse_result_t)browseResult {
|
||||
return nw_browse_result_copy_txt_record_object(browseResult);
|
||||
}
|
||||
|
||||
- (void)applyTXTRecord:(nw_txt_record_t)txtRecord block:(nw_txt_record_applier_t)block {
|
||||
nw_txt_record_apply(txtRecord, block);
|
||||
}
|
||||
|
||||
- (nw_browse_result_change_t)getChangesFrom:(nw_browse_result_t)oldResult
|
||||
to:(nw_browse_result_t)newResult {
|
||||
return nw_browse_result_get_changes(oldResult, newResult);
|
||||
}
|
||||
|
||||
- (nullable nw_endpoint_t)copyEndpointFromResult:(nw_browse_result_t)result {
|
||||
return nw_browse_result_copy_endpoint(result);
|
||||
}
|
||||
|
||||
- (nullable NSString *)getBonjourServiceNameFromEndpoint:(nw_endpoint_t)endpoint {
|
||||
const char *name = nw_endpoint_get_bonjour_service_name(endpoint);
|
||||
return name ? @(name) : nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,77 @@
|
||||
// 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 <Network/Network.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* A protocol that wraps nw_browser_t functions for testability.
|
||||
*/
|
||||
@protocol GNCNWBrowser <NSObject>
|
||||
|
||||
/**
|
||||
* Creates a new browser object with a browse descriptor and parameters.
|
||||
*
|
||||
* @param descriptor The descriptor that defines the service to browse for.
|
||||
* @param parameters The parameters to use for browsing
|
||||
* @return An initialized browser object.
|
||||
*/
|
||||
- (nw_browser_t)createWithDescriptor:(nw_browse_descriptor_t)descriptor
|
||||
parameters:(nw_parameters_t)parameters;
|
||||
|
||||
/**
|
||||
* Sets the dispatch queue on which to deliver browser events.
|
||||
*
|
||||
* @param browser The browser object to modify.
|
||||
* @param queue The dispatch queue to use for browser events.
|
||||
*/
|
||||
- (void)setQueue:(nw_browser_t)browser queue:(dispatch_queue_t)queue;
|
||||
|
||||
/**
|
||||
* Sets a handler that is called when the set of discovered browse results changes.
|
||||
*
|
||||
* @param browser The browser object to modify.
|
||||
* @param handler The handler to call when browse results change.
|
||||
*/
|
||||
- (void)setBrowseResultsChangedHandler:(nw_browser_t)browser
|
||||
handler:(nw_browser_browse_results_changed_handler_t)handler;
|
||||
|
||||
/**
|
||||
* Sets a handler that is called when the browser state changes.
|
||||
*
|
||||
* @param browser The browser object to modify.
|
||||
* @param handler The handler to call when the browser state changes.
|
||||
*/
|
||||
- (void)setStateChangedHandler:(nw_browser_t)browser
|
||||
handler:(nw_browser_state_changed_handler_t)handler;
|
||||
|
||||
/**
|
||||
* Starts the browser, which will begin browsing for services.
|
||||
*
|
||||
* @param browser The browser object to start.
|
||||
*/
|
||||
- (void)start:(nw_browser_t)browser;
|
||||
|
||||
/**
|
||||
* Cancels the browser, which will stop browsing for services and invalidate the object.
|
||||
*
|
||||
* @param browser The browser object to cancel.
|
||||
*/
|
||||
- (void)cancel:(nw_browser_t)browser;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -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 "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWBrowser.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface GNCNWBrowserImpl : NSObject <GNCNWBrowser>
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,52 @@
|
||||
// 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/Mediums/WiFiCommon/GNCNWBrowserImpl.h"
|
||||
|
||||
#import <Network/Network.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation GNCNWBrowserImpl
|
||||
|
||||
- (nw_browser_t)createWithDescriptor:(nw_browse_descriptor_t)descriptor
|
||||
parameters:(nw_parameters_t)parameters {
|
||||
return nw_browser_create(descriptor, parameters);
|
||||
}
|
||||
|
||||
- (void)setQueue:(nw_browser_t)browser queue:(dispatch_queue_t)queue {
|
||||
nw_browser_set_queue(browser, queue);
|
||||
}
|
||||
|
||||
- (void)setBrowseResultsChangedHandler:(nw_browser_t)browser
|
||||
handler:(nw_browser_browse_results_changed_handler_t)handler {
|
||||
nw_browser_set_browse_results_changed_handler(browser, handler);
|
||||
}
|
||||
|
||||
- (void)setStateChangedHandler:(nw_browser_t)browser
|
||||
handler:(nw_browser_state_changed_handler_t)handler {
|
||||
nw_browser_set_state_changed_handler(browser, handler);
|
||||
}
|
||||
|
||||
- (void)start:(nw_browser_t)browser {
|
||||
nw_browser_start(browser);
|
||||
}
|
||||
|
||||
- (void)cancel:(nw_browser_t)browser {
|
||||
nw_browser_cancel(browser);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -24,6 +24,8 @@ objc_library(
|
||||
name = "FakeNWFramework",
|
||||
testonly = True,
|
||||
srcs = [
|
||||
"GNCFakeNWBrowseResult.m",
|
||||
"GNCFakeNWBrowser.m",
|
||||
"GNCFakeNWConnection.m",
|
||||
"GNCFakeNWFramework.m",
|
||||
"GNCFakeNWFrameworkServerSocket.m",
|
||||
@@ -31,6 +33,8 @@ objc_library(
|
||||
"GNCFakeNWListener.m",
|
||||
],
|
||||
hdrs = [
|
||||
"GNCFakeNWBrowseResult.h",
|
||||
"GNCFakeNWBrowser.h",
|
||||
"GNCFakeNWConnection.h",
|
||||
"GNCFakeNWFramework.h",
|
||||
"GNCFakeNWFrameworkServerSocket.h",
|
||||
@@ -49,6 +53,8 @@ objc_library(
|
||||
testonly = True,
|
||||
srcs = [
|
||||
"GNCIPAddressTest.mm",
|
||||
"GNCNWBrowseResultImplTest.m",
|
||||
"GNCNWBrowserImplTest.m",
|
||||
"GNCNWConnectionImplTest.m",
|
||||
"GNCNWFrameworkServerSocketTest.m",
|
||||
"GNCNWFrameworkSocketTest.m",
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
// 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/Mediums/WiFiCommon/GNCNWBrowseResult.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Network/Network.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// Fake interface for testing
|
||||
@interface GNCFakeNWInterface : NSObject <OS_nw_interface>
|
||||
@property(nonatomic) nw_interface_type_t type;
|
||||
@end
|
||||
|
||||
@interface GNCFakeNWBrowseResult : NSObject <GNCNWBrowseResult>
|
||||
@property(nonatomic, copy) NSArray<GNCFakeNWInterface *> *interfaces;
|
||||
@property(nonatomic, nullable) NSDictionary<NSString *, NSString *> *txtRecord;
|
||||
|
||||
@property(nonatomic) nw_browse_result_change_t getChangesFromResult;
|
||||
@property(nonatomic, nullable) nw_endpoint_t endpointFromResultResult;
|
||||
@property(nonatomic, nullable) NSString *getBonjourServiceNameFromEndpointResult;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
// 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/Mediums/WiFiCommon/Tests/GNCFakeNWBrowseResult.h"
|
||||
|
||||
#import <Network/Network.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation GNCFakeNWInterface
|
||||
@end
|
||||
|
||||
@implementation GNCFakeNWBrowseResult
|
||||
|
||||
- (void)enumerateInterfaces:(nw_browse_result_t)browseResult
|
||||
usingBlock:(nw_browse_result_enumerate_interface_t)block {
|
||||
for (GNCFakeNWInterface *interface in self.interfaces) {
|
||||
if (!block((nw_interface_t)interface)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (nw_interface_type_t)interfaceGetType:(nw_interface_t)interface {
|
||||
return ((GNCFakeNWInterface *)interface).type;
|
||||
}
|
||||
|
||||
- (nullable nw_txt_record_t)copyTXTRecordObject:(nw_browse_result_t)browseResult {
|
||||
return (nw_txt_record_t)browseResult;
|
||||
}
|
||||
|
||||
- (void)applyTXTRecord:(nw_txt_record_t)txtRecord block:(nw_txt_record_applier_t)block {
|
||||
GNCFakeNWBrowseResult *result = (GNCFakeNWBrowseResult *)txtRecord;
|
||||
if (!result.txtRecord) {
|
||||
return;
|
||||
}
|
||||
[result.txtRecord enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value,
|
||||
BOOL *stop) {
|
||||
const char *keyUTF8 = key.UTF8String;
|
||||
const uint8_t *valueUTF8 = (const uint8_t *)value.UTF8String;
|
||||
size_t valueLen = value.length;
|
||||
block(keyUTF8, nw_txt_record_find_key_non_empty_value, valueUTF8, valueLen);
|
||||
}];
|
||||
}
|
||||
|
||||
- (nw_browse_result_change_t)getChangesFrom:(nw_browse_result_t)oldResult
|
||||
to:(nw_browse_result_t)newResult {
|
||||
return self.getChangesFromResult;
|
||||
}
|
||||
|
||||
- (nullable nw_endpoint_t)copyEndpointFromResult:(nw_browse_result_t)result {
|
||||
if (self.endpointFromResultResult) {
|
||||
return self.endpointFromResultResult;
|
||||
}
|
||||
return nw_endpoint_create_host("fakehost", "1234");
|
||||
}
|
||||
|
||||
- (nullable NSString *)getBonjourServiceNameFromEndpoint:(nw_endpoint_t)endpoint {
|
||||
return self.getBonjourServiceNameFromEndpointResult ?: @"FakeService";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,35 @@
|
||||
// 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 <Network/Network.h>
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWBrowser.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface GNCFakeNWBrowser : NSObject <GNCNWBrowser>
|
||||
|
||||
@property(nonatomic, nullable) nw_browser_t createWithDescriptorResult;
|
||||
@property(nonatomic) BOOL simulateTimeout;
|
||||
@property(nonatomic) nw_browser_state_t stateForStart;
|
||||
@property(nonatomic, nullable) dispatch_queue_t setQueueQueue;
|
||||
@property(nonatomic, nullable)
|
||||
nw_browser_browse_results_changed_handler_t browseResultsChangedHandler;
|
||||
@property(nonatomic, nullable) nw_browser_state_changed_handler_t stateChangedHandler;
|
||||
@property(nonatomic, readonly) BOOL cancelCalled;
|
||||
@property(nonatomic, nullable, readonly) nw_browser_t cancelledBrowser;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,72 @@
|
||||
// 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/Mediums/WiFiCommon/Tests/GNCFakeNWBrowser.h"
|
||||
|
||||
@implementation GNCFakeNWBrowser
|
||||
|
||||
@synthesize createWithDescriptorResult = _createWithDescriptorResult;
|
||||
@synthesize setQueueQueue = _setQueueQueue;
|
||||
@synthesize browseResultsChangedHandler = _browseResultsChangedHandler;
|
||||
@synthesize stateChangedHandler = _stateChangedHandler;
|
||||
@synthesize cancelCalled = _cancelCalled;
|
||||
@synthesize cancelledBrowser = _cancelledBrowser;
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_stateForStart = nw_browser_state_ready;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nw_browser_t)createWithDescriptor:(nw_browse_descriptor_t)descriptor
|
||||
parameters:(nw_parameters_t)parameters {
|
||||
// Return a unique object to represent the browser
|
||||
_createWithDescriptorResult = (nw_browser_t)[[NSObject alloc] init];
|
||||
return _createWithDescriptorResult;
|
||||
}
|
||||
|
||||
- (void)setQueue:(nw_browser_t)browser queue:(dispatch_queue_t)queue {
|
||||
self.setQueueQueue = queue;
|
||||
}
|
||||
|
||||
- (void)setBrowseResultsChangedHandler:(nw_browser_t)browser
|
||||
handler:(nw_browser_browse_results_changed_handler_t)handler {
|
||||
self.browseResultsChangedHandler = handler;
|
||||
}
|
||||
|
||||
- (void)setStateChangedHandler:(nw_browser_t)browser
|
||||
handler:(nw_browser_state_changed_handler_t)handler {
|
||||
self.stateChangedHandler = handler;
|
||||
}
|
||||
|
||||
- (void)start:(nw_browser_t)browser {
|
||||
if (_simulateTimeout) {
|
||||
return;
|
||||
}
|
||||
// Simulate state change
|
||||
if (self.stateChangedHandler) {
|
||||
dispatch_async(self.setQueueQueue ?: dispatch_get_main_queue(), ^{
|
||||
self.stateChangedHandler(self.stateForStart, nil);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancel:(nw_browser_t)browser {
|
||||
_cancelCalled = YES;
|
||||
_cancelledBrowser = browser;
|
||||
}
|
||||
|
||||
@end
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
// 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/Mediums/WiFiCommon/GNCNWBrowseResultImpl.h"
|
||||
|
||||
#import <Network/Network.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface GNCNWBrowseResultImplTest : XCTestCase
|
||||
@end
|
||||
|
||||
@implementation GNCNWBrowseResultImplTest
|
||||
|
||||
- (void)testInit {
|
||||
GNCNWBrowseResultImpl *browseResult = [[GNCNWBrowseResultImpl alloc] init];
|
||||
XCTAssertNotNil(browseResult);
|
||||
}
|
||||
|
||||
- (void)testGetBonjourServiceName {
|
||||
GNCNWBrowseResultImpl *browseResult = [[GNCNWBrowseResultImpl alloc] init];
|
||||
nw_endpoint_t endpoint =
|
||||
nw_endpoint_create_bonjour_service("MyService", "_servicetype._tcp", "local.");
|
||||
NSString *serviceName = [browseResult getBonjourServiceNameFromEndpoint:endpoint];
|
||||
XCTAssertEqualObjects(serviceName, @"MyService");
|
||||
}
|
||||
|
||||
- (void)testGetBonjourServiceName_NonBonjour {
|
||||
GNCNWBrowseResultImpl *browseResult = [[GNCNWBrowseResultImpl alloc] init];
|
||||
nw_endpoint_t endpoint = nw_endpoint_create_host("google.com", "443");
|
||||
NSString *serviceName = [browseResult getBonjourServiceNameFromEndpoint:endpoint];
|
||||
XCTAssertNil(serviceName);
|
||||
}
|
||||
|
||||
- (void)testApplyTXTRecord {
|
||||
GNCNWBrowseResultImpl *browseResult = [[GNCNWBrowseResultImpl alloc] init];
|
||||
nw_txt_record_t txtRecord = nw_txt_record_create_dictionary();
|
||||
NSData *value1Data = [@"value1" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSData *value2Data = [@"value2" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
nw_txt_record_set_key(txtRecord, "key1", value1Data.bytes, value1Data.length);
|
||||
nw_txt_record_set_key(txtRecord, "key2", value2Data.bytes, value2Data.length);
|
||||
NSMutableDictionary<NSString *, NSString *> *results = [[NSMutableDictionary alloc] init];
|
||||
[browseResult applyTXTRecord:txtRecord
|
||||
block:^bool(const char *key, nw_txt_record_find_key_t found,
|
||||
const uint8_t *value, size_t value_len) {
|
||||
if (found == nw_txt_record_find_key_non_empty_value) {
|
||||
NSString *valueString =
|
||||
[[NSString alloc] initWithBytes:value
|
||||
length:value_len
|
||||
encoding:NSUTF8StringEncoding];
|
||||
[results setObject:valueString forKey:@(key)];
|
||||
}
|
||||
return YES;
|
||||
}];
|
||||
XCTAssertEqual(results.count, 2);
|
||||
XCTAssertEqualObjects(results[@"key1"], @"value1");
|
||||
XCTAssertEqualObjects(results[@"key2"], @"value2");
|
||||
}
|
||||
|
||||
@end
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// 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/Mediums/WiFiCommon/GNCNWBrowserImpl.h"
|
||||
|
||||
#import <Network/Network.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface GNCNWBrowserImplTest : XCTestCase
|
||||
@end
|
||||
|
||||
@implementation GNCNWBrowserImplTest
|
||||
|
||||
- (void)testInit {
|
||||
GNCNWBrowserImpl *browser = [[GNCNWBrowserImpl alloc] init];
|
||||
XCTAssertNotNil(browser);
|
||||
}
|
||||
|
||||
// NOTE: The methods in GNCNWBrowserImpl call C functions from the Network.framework
|
||||
// (e.g., nw_browser_create, nw_browser_start, nw_browser_cancel).
|
||||
// OCMock cannot directly mock these C functions. To test these interactions,
|
||||
// a lower-level interception method or a different testing strategy would be required.
|
||||
// We can only test the basic initialization here.
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user