From 76768e3eb15ee7643e2092ccf3c2e4d1ff233d7d Mon Sep 17 00:00:00 2001 From: Karsten Sperling Date: Tue, 17 Dec 2024 11:56:21 +1300 Subject: [PATCH] Darwin: Tidy up some device type meta-data classes - Move MTRDeviceTypeRevision out of ServerEndpoint directory - Move MTRProductIdentity into its own file - Implement NSCopying and equality on MTRDeviceType and MTRProductIdentity - Implement description on all 3 types - Add tests --- .../CHIP/MTRDeviceControllerDelegate.h | 20 ++--- src/darwin/Framework/CHIP/MTRDeviceType.h | 9 +- src/darwin/Framework/CHIP/MTRDeviceType.mm | 44 ++++++++-- .../MTRDeviceTypeRevision.h | 14 +++ .../MTRDeviceTypeRevision.mm | 30 +++++-- src/darwin/Framework/CHIP/MTREndpointInfo.h | 25 ++++++ src/darwin/Framework/CHIP/MTREndpointInfo.mm | 21 +++++ .../Framework/CHIP/MTRProductIdentity.h | 41 +++++++++ .../Framework/CHIP/MTRProductIdentity.mm | 58 +++++++++++++ src/darwin/Framework/CHIP/Matter.h | 1 + .../CHIPTests/MTRDeviceTypeRevisionTests.m | 85 +++++++++++++++++++ .../Framework/CHIPTests/MTRDeviceTypeTests.m | 25 +++++- .../CHIPTests/MTRProductIdentityTests.m | 53 ++++++++++++ .../Matter.xcodeproj/project.pbxproj | 20 ++++- 14 files changed, 410 insertions(+), 36 deletions(-) rename src/darwin/Framework/CHIP/{ServerEndpoint => }/MTRDeviceTypeRevision.h (75%) rename src/darwin/Framework/CHIP/{ServerEndpoint => }/MTRDeviceTypeRevision.mm (76%) create mode 100644 src/darwin/Framework/CHIP/MTREndpointInfo.h create mode 100644 src/darwin/Framework/CHIP/MTREndpointInfo.mm create mode 100644 src/darwin/Framework/CHIP/MTRProductIdentity.h create mode 100644 src/darwin/Framework/CHIP/MTRProductIdentity.mm create mode 100644 src/darwin/Framework/CHIPTests/MTRDeviceTypeRevisionTests.m create mode 100644 src/darwin/Framework/CHIPTests/MTRProductIdentityTests.m diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDelegate.h b/src/darwin/Framework/CHIP/MTRDeviceControllerDelegate.h index bd575e5a42def3..923c2ee675dd3b 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerDelegate.h +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDelegate.h @@ -20,6 +20,11 @@ NS_ASSUME_NONNULL_BEGIN +@class MTRDeviceController; +@class MTRDeviceTypeRevision; +@class MTRMetrics; +@class MTRProductIdentity; + typedef NS_ENUM(NSInteger, MTRCommissioningStatus) { MTRCommissioningStatusUnknown = 0, MTRCommissioningStatusSuccess = 1, @@ -29,21 +34,6 @@ typedef NS_ENUM(NSInteger, MTRCommissioningStatus) { = 3, } MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -/** - * A representation of a (vendor, product) pair that identifies a specific product. - */ -MTR_AVAILABLE(ios(17.0), macos(14.0), watchos(10.0), tvos(17.0)) -@interface MTRProductIdentity : NSObject - -@property (nonatomic, copy, readonly) NSNumber * vendorID; - -@property (nonatomic, copy, readonly) NSNumber * productID; - -- (instancetype)initWithVendorID:(NSNumber *)vendorID productID:(NSNumber *)productID; -@end - -@class MTRDeviceController; -@class MTRMetrics; /** * The protocol definition for the MTRDeviceControllerDelegate. diff --git a/src/darwin/Framework/CHIP/MTRDeviceType.h b/src/darwin/Framework/CHIP/MTRDeviceType.h index 0330b76d1533a2..54802a19e12dd6 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceType.h +++ b/src/darwin/Framework/CHIP/MTRDeviceType.h @@ -23,8 +23,11 @@ NS_ASSUME_NONNULL_BEGIN +/** + * Meta-data about a device type defined in the Matter specification. + */ MTR_AVAILABLE(ios(18.2), macos(15.2), watchos(11.2), tvos(18.2)) -@interface MTRDeviceType : NSObject +@interface MTRDeviceType : NSObject /* (see below) */ /** * Returns an MTRDeviceType for the given ID, if the ID is known. Returns nil @@ -52,4 +55,8 @@ MTR_AVAILABLE(ios(18.2), macos(15.2), watchos(11.2), tvos(18.2)) @end +MTR_NEWLY_AVAILABLE +@interface MTRDeviceType () +@end + NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDeviceType.mm b/src/darwin/Framework/CHIP/MTRDeviceType.mm index 394640d2d72b2a..30d71e1b66f263 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceType.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceType.mm @@ -17,21 +17,21 @@ #import +#import "MTRDefines_Internal.h" #import "MTRDeviceTypeMetadata.h" #import "MTRLogging_Internal.h" #include +#include using namespace chip; +MTR_DIRECT_MEMBERS @implementation MTRDeviceType -- (nullable instancetype)initWithDeviceTypeID:(NSNumber *)id name:(NSString *)name isUtility:(BOOL)isUtility +- (instancetype)initWithDeviceTypeID:(NSNumber *)id name:(NSString *)name isUtility:(BOOL)isUtility { - if (!(self = [super init])) { - return nil; - } - + self = [super init]; _id = id; _name = name; _isUtility = isUtility; @@ -50,10 +50,36 @@ + (nullable MTRDeviceType *)deviceTypeForID:(NSNumber *)deviceTypeID return nil; } - return [[MTRDeviceType alloc] - initWithDeviceTypeID:deviceTypeID - name:[NSString stringWithUTF8String:deviceTypeData->name] - isUtility:(deviceTypeData->deviceClass != MTRDeviceTypeClass::Simple)]; + auto * name = [[NSString alloc] initWithBytesNoCopy:(void *)deviceTypeData->name + length:strlen(deviceTypeData->name) + encoding:NSUTF8StringEncoding freeWhenDone:NO]; + + return [[MTRDeviceType alloc] initWithDeviceTypeID:deviceTypeID + name:name + isUtility:(deviceTypeData->deviceClass != MTRDeviceTypeClass::Simple)]; +} + +- (id)copyWithZone:(NSZone *)zone +{ + return self; // immutable +} + +- (NSUInteger)hash +{ + return _id.hash; +} + +- (BOOL)isEqual:(id)object +{ + VerifyOrReturnValue([object class] == [self class], NO); + MTRDeviceType * other = object; + return [_id isEqual:other->_id]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@ 0x%" PRIx32 " (%@)>", + self.class, _id.unsignedIntValue, _name]; } @end diff --git a/src/darwin/Framework/CHIP/ServerEndpoint/MTRDeviceTypeRevision.h b/src/darwin/Framework/CHIP/MTRDeviceTypeRevision.h similarity index 75% rename from src/darwin/Framework/CHIP/ServerEndpoint/MTRDeviceTypeRevision.h rename to src/darwin/Framework/CHIP/MTRDeviceTypeRevision.h index 517948816364c2..55865ed952b719 100644 --- a/src/darwin/Framework/CHIP/ServerEndpoint/MTRDeviceTypeRevision.h +++ b/src/darwin/Framework/CHIP/MTRDeviceTypeRevision.h @@ -17,6 +17,9 @@ #import #import +@class MTRDescriptorClusterDeviceTypeStruct; +@class MTRDeviceType; + NS_ASSUME_NONNULL_BEGIN /** @@ -38,9 +41,20 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) */ - (nullable instancetype)initWithDeviceTypeID:(NSNumber *)deviceTypeID revision:(NSNumber *)revision; +/** + * Initializes the receiver based on the values in the specified struct. + */ +- (nullable instancetype)initWithDeviceTypeStruct:(MTRDescriptorClusterDeviceTypeStruct *)deviceTypeStruct MTR_NEWLY_AVAILABLE; + @property (nonatomic, copy, readonly) NSNumber * deviceTypeID; @property (nonatomic, copy, readonly) NSNumber * deviceTypeRevision; +/** + * Returns the MTRDeviceType corresponding to deviceTypeID, + * or nil if deviceTypeID does not represent a known device type. + */ +@property (nonatomic, copy, readonly, nullable) MTRDeviceType * typeInformation MTR_NEWLY_AVAILABLE; + @end NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/ServerEndpoint/MTRDeviceTypeRevision.mm b/src/darwin/Framework/CHIP/MTRDeviceTypeRevision.mm similarity index 76% rename from src/darwin/Framework/CHIP/ServerEndpoint/MTRDeviceTypeRevision.mm rename to src/darwin/Framework/CHIP/MTRDeviceTypeRevision.mm index de5782c92e4aeb..e637f83543f83b 100644 --- a/src/darwin/Framework/CHIP/ServerEndpoint/MTRDeviceTypeRevision.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceTypeRevision.mm @@ -14,12 +14,15 @@ * limitations under the License. */ +#import "MTRDeviceTypeRevision.h" #import "MTRDefines_Internal.h" +#import "MTRDeviceType.h" #import "MTRLogging_Internal.h" -#import +#import "MTRStructsObjc.h" #include #include +#include #include using namespace chip; @@ -29,6 +32,9 @@ @implementation MTRDeviceTypeRevision - (nullable instancetype)initWithDeviceTypeID:(NSNumber *)deviceTypeID revision:(NSNumber *)revision { + VerifyOrReturnValue(deviceTypeID != nil, nil); + VerifyOrReturnValue(revision != nil, nil); + auto deviceTypeIDValue = deviceTypeID.unsignedLongLongValue; if (!CanCastTo(deviceTypeIDValue)) { MTR_LOG_ERROR("MTRDeviceTypeRevision provided too-large device type ID: 0x%llx", deviceTypeIDValue); @@ -50,19 +56,26 @@ - (nullable instancetype)initWithDeviceTypeID:(NSNumber *)deviceTypeID revision: return [self initInternalWithDeviceTypeID:[deviceTypeID copy] revision:[revision copy]]; } +- (instancetype)initWithDeviceTypeStruct:(MTRDescriptorClusterDeviceTypeStruct *)deviceTypeStruct +{ + return [self initWithDeviceTypeID:deviceTypeStruct.deviceType revision:deviceTypeStruct.revision]; +} + // initInternalWithDeviceTypeID:revision assumes that the device type ID and device // revision have already been validated and, if needed, copied from the input. - (instancetype)initInternalWithDeviceTypeID:(NSNumber *)deviceTypeID revision:(NSNumber *)revision { - if (!(self = [super init])) { - return nil; - } - + self = [super init]; _deviceTypeID = deviceTypeID; _deviceTypeRevision = revision; return self; } +- (MTRDeviceType *)typeInformation +{ + return [MTRDeviceType deviceTypeForID:_deviceTypeID]; +} + - (id)copyWithZone:(NSZone *)zone { // We have no mutable state. @@ -85,4 +98,11 @@ - (NSUInteger)hash return _deviceTypeID.unsignedLongValue ^ _deviceTypeRevision.unsignedShortValue; } +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@ 0x%" PRIx32 " (%@) rev %d>", + self.class, _deviceTypeID.unsignedIntValue, + self.typeInformation.name ?: @"???", _deviceTypeRevision.unsignedIntValue]; +} + @end diff --git a/src/darwin/Framework/CHIP/MTREndpointInfo.h b/src/darwin/Framework/CHIP/MTREndpointInfo.h new file mode 100644 index 00000000000000..a204ddcb92d0d9 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTREndpointInfo.h @@ -0,0 +1,25 @@ +///** + * Copyright (c) 2024 Project CHIP Authors + * + * 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 + * + * http://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 + +NS_ASSUME_NONNULL_BEGIN + +@interface MTREndpointInfo : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTREndpointInfo.mm b/src/darwin/Framework/CHIP/MTREndpointInfo.mm new file mode 100644 index 00000000000000..fa9175c635e957 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTREndpointInfo.mm @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * 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 + * + * http://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 "MTREndpointInfo.h" + +@implementation MTREndpointInfo + +@end diff --git a/src/darwin/Framework/CHIP/MTRProductIdentity.h b/src/darwin/Framework/CHIP/MTRProductIdentity.h new file mode 100644 index 00000000000000..88183188369d91 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRProductIdentity.h @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * 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 + * + * http://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 + +NS_ASSUME_NONNULL_BEGIN + +/** + * A representation of a (vendor, product) pair that identifies a specific product. + */ +MTR_AVAILABLE(ios(17.0), macos(14.0), watchos(10.0), tvos(17.0)) +@interface MTRProductIdentity : NSObject /* (see below) */ + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +- (instancetype)initWithVendorID:(NSNumber *)vendorID productID:(NSNumber *)productID; + +@property (nonatomic, copy, readonly) NSNumber * vendorID; +@property (nonatomic, copy, readonly) NSNumber * productID; + +@end + +MTR_NEWLY_AVAILABLE +@interface MTRProductIdentity () +@end + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRProductIdentity.mm b/src/darwin/Framework/CHIP/MTRProductIdentity.mm new file mode 100644 index 00000000000000..3aaa286abc11c9 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRProductIdentity.mm @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * 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 + * + * http://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 "MTRProductIdentity.h" + +#import "MTRDefines_Internal.h" +#import "MTRUtilities.h" + +#include + +MTR_DIRECT_MEMBERS +@implementation MTRProductIdentity + +- (instancetype)initWithVendorID:(NSNumber *)vendorID productID:(NSNumber *)productID +{ + self = [super init]; + VerifyOrReturnValue(vendorID != nil && productID != nil, nil); + _vendorID = vendorID; + _productID = productID; + return self; +} + +- (id)copyWithZone:(NSZone *)zone +{ + return self; // immutable +} + +- (NSUInteger)hash +{ + return _vendorID.hash ^ _productID.hash; +} + +- (BOOL)isEqual:(id)object +{ + VerifyOrReturnValue([object class] == [self class], NO); + MTRProductIdentity * other = object; + return MTREqualObjects(_vendorID, other.vendorID) && MTREqualObjects(_productID, other.productID); +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: vid 0x%u pid 0x%u>", self.class, _vendorID.unsignedIntValue, _productID.unsignedIntValue]; +} + +@end diff --git a/src/darwin/Framework/CHIP/Matter.h b/src/darwin/Framework/CHIP/Matter.h index 85a87c4ba12c0c..9387480e771c5b 100644 --- a/src/darwin/Framework/CHIP/Matter.h +++ b/src/darwin/Framework/CHIP/Matter.h @@ -62,6 +62,7 @@ #import #import #import +#import #import #import #import diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTypeRevisionTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTypeRevisionTests.m new file mode 100644 index 00000000000000..a9f69854917e26 --- /dev/null +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTypeRevisionTests.m @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * 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 + * + * http://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 +#import + +@interface MTRDeviceTypeRevisionTests : XCTestCase +@end + +@implementation MTRDeviceTypeRevisionTests + +- (void)testInvalidTypeID +{ + XCTAssertNil([[MTRDeviceTypeRevision alloc] initWithDeviceTypeID:(id _Nonnull) nil revision:@1]); + XCTAssertNil([[MTRDeviceTypeRevision alloc] initWithDeviceTypeID:@0xC000 revision:@1]); // type > 0xBFFF + XCTAssertNil([[MTRDeviceTypeRevision alloc] initWithDeviceTypeID:@0x100000000 revision:@1]); +} + +- (void)testInvalidRevision +{ + XCTAssertNil([[MTRDeviceTypeRevision alloc] initWithDeviceTypeID:@1 revision:(id _Nonnull) nil]); + XCTAssertNil([[MTRDeviceTypeRevision alloc] initWithDeviceTypeID:@1 revision:@0]); // < 1 + XCTAssertNil([[MTRDeviceTypeRevision alloc] initWithDeviceTypeID:@1 revision:@0x10000]); // > 0xFFFF +} + +- (void)testInitWithStruct +{ + MTRDescriptorClusterDeviceTypeStruct * strukt = [[MTRDescriptorClusterDeviceTypeStruct alloc] init]; + strukt.deviceType = @42; + strukt.revision = @2; + MTRDeviceTypeRevision * typeRev = [[MTRDeviceTypeRevision alloc] initWithDeviceTypeStruct:strukt]; + XCTAssertNotNil(typeRev); + XCTAssertEqualObjects(typeRev, [[MTRDeviceTypeRevision alloc] initWithDeviceTypeID:@42 revision:@2]); +} + +- (void)testTypeInformation +{ + __auto_type * typeRev = [[MTRDeviceTypeRevision alloc] initWithDeviceTypeID:@(MTRDeviceTypeIDTypeRootNodeID) revision:@1]; + XCTAssertNotNil(typeRev); + XCTAssertNotNil(typeRev.typeInformation); + XCTAssertEqualObjects(typeRev.typeInformation.name, @"Root Node"); +} + +- (void)testEqualityAndCopying +{ + __auto_type * a1 = [[MTRDeviceTypeRevision alloc] initWithDeviceTypeID:@(MTRDeviceTypeIDTypeMicrowaveOvenID) revision:@1]; + XCTAssertNotNil(a1); + XCTAssertTrue([a1 isEqual:a1]); + XCTAssertTrue([a1 isEqual:[a1 copy]]); + XCTAssertFalse([a1 isEqual:nil]); + XCTAssertFalse([a1 isEqual:@(MTRDeviceTypeIDTypeMicrowaveOvenID)]); + + __auto_type * a2 = [[MTRDeviceTypeRevision alloc] initWithDeviceTypeID:@(MTRDeviceTypeIDTypeMicrowaveOvenID) revision:@1]; + XCTAssertNotNil(a2); + XCTAssertEqual(a1.hash, a2.hash); + XCTAssertTrue([a1 isEqual:a2]); + XCTAssertTrue([a2 isEqual:a1]); + + __auto_type * b = [[MTRDeviceTypeRevision alloc] initWithDeviceTypeID:@(MTRDeviceTypeIDTypePowerSourceID) revision:@1]; + XCTAssertNotNil(b); + XCTAssertFalse([a1 isEqual:b]); + XCTAssertFalse([b isEqual:a1]); + + __auto_type * c = [[MTRDeviceTypeRevision alloc] initWithDeviceTypeID:@(MTRDeviceTypeIDTypeMicrowaveOvenID) revision:@2]; + XCTAssertNotNil(c); + XCTAssertFalse([c isEqual:a1]); + XCTAssertFalse([a1 isEqual:c]); + XCTAssertFalse([c isEqual:b]); + XCTAssertFalse([b isEqual:c]); +} + +@end diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTypeTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTypeTests.m index 7a41d42b40cb43..1a3f3fc740c722 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTypeTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTypeTests.m @@ -15,12 +15,9 @@ */ #import - -// system dependencies #import @interface MTRDeviceTypeTests : XCTestCase - @end @implementation MTRDeviceTypeTests @@ -55,7 +52,7 @@ - (void)testKnownUtilityID XCTAssertTrue(deviceType.isUtility); } -- (void)testRootNodeID +- (void)testPowerSource { __auto_type * deviceType = [MTRDeviceType deviceTypeForID:@(MTRDeviceTypeIDTypePowerSourceID)]; XCTAssertNotNil(deviceType); @@ -64,4 +61,24 @@ - (void)testRootNodeID XCTAssertTrue(deviceType.isUtility); } +- (void)testEqualityAndCopying +{ + __auto_type * a1 = [MTRDeviceType deviceTypeForID:@(MTRDeviceTypeIDTypeMicrowaveOvenID)]; + XCTAssertNotNil(a1); + XCTAssertTrue([a1 isEqual:a1]); + XCTAssertFalse([a1 isEqual:nil]); + XCTAssertFalse([a1 isEqual:@(MTRDeviceTypeIDTypeMicrowaveOvenID)]); + + __auto_type * a2 = [MTRDeviceType deviceTypeForID:@(MTRDeviceTypeIDTypeMicrowaveOvenID)]; + XCTAssertNotNil(a2); + XCTAssertEqual(a1.hash, a2.hash); + XCTAssertTrue([a1 isEqual:a2]); + XCTAssertTrue([a2 isEqual:a1]); + + __auto_type * b = [MTRDeviceType deviceTypeForID:@(MTRDeviceTypeIDTypePowerSourceID)]; + XCTAssertNotNil(b); + XCTAssertFalse([a1 isEqual:b]); + XCTAssertFalse([b isEqual:a1]); +} + @end diff --git a/src/darwin/Framework/CHIPTests/MTRProductIdentityTests.m b/src/darwin/Framework/CHIPTests/MTRProductIdentityTests.m new file mode 100644 index 00000000000000..4974a4077f4563 --- /dev/null +++ b/src/darwin/Framework/CHIPTests/MTRProductIdentityTests.m @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * 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 + * + * http://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 +#import + +@interface MTRProductIdentityTests : XCTestCase + +@end + +@implementation MTRProductIdentityTests + +- (void)testEqualityAndCopying +{ + MTRProductIdentity * a1 = [[MTRProductIdentity alloc] initWithVendorID:@1 productID:@1]; + XCTAssertNotNil(a1); + XCTAssertTrue([a1 isEqual:a1]); + XCTAssertTrue([a1 isEqual:[a1 copy]]); + XCTAssertFalse([a1 isEqual:nil]); + XCTAssertFalse([a1 isEqual:@1]); + + MTRProductIdentity * a2 = [[MTRProductIdentity alloc] initWithVendorID:@1 productID:@1]; + XCTAssertNotNil(a2); + XCTAssertTrue([a1 isEqual:a2]); + XCTAssertTrue([a2 isEqual:a1]); + + MTRProductIdentity * b = [[MTRProductIdentity alloc] initWithVendorID:@1 productID:@555]; + XCTAssertNotNil(b); + XCTAssertFalse([b isEqual:a1]); + XCTAssertFalse([a1 isEqual:b]); + + MTRProductIdentity * c = [[MTRProductIdentity alloc] initWithVendorID:@555 productID:@1]; + XCTAssertNotNil(c); + XCTAssertFalse([c isEqual:a1]); + XCTAssertFalse([a1 isEqual:c]); + XCTAssertFalse([c isEqual:b]); + XCTAssertFalse([b isEqual:c]); +} + +@end diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index f2b89f0ca48a3f..3c729c115aa39e 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -116,6 +116,10 @@ 3D843717294979230070D20A /* MTRClusters_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D843715294979230070D20A /* MTRClusters_Internal.h */; }; 3D843756294AD25A0070D20A /* MTRCertificateInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D843754294AD25A0070D20A /* MTRCertificateInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3D843757294AD25A0070D20A /* MTRCertificateInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D843755294AD25A0070D20A /* MTRCertificateInfo.mm */; }; + 3D9F2FBE2D10DB4F003CA2BB /* MTRProductIdentity.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D9F2FBC2D10DB4F003CA2BB /* MTRProductIdentity.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3D9F2FBF2D10DB4F003CA2BB /* MTRProductIdentity.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D9F2FBD2D10DB4F003CA2BB /* MTRProductIdentity.mm */; }; + 3D9F2FC12D10DCA2003CA2BB /* MTRProductIdentityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D9F2FC02D10DCA2003CA2BB /* MTRProductIdentityTests.m */; }; + 3D9F2FC32D10E207003CA2BB /* MTRDeviceTypeRevisionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D9F2FC22D10E207003CA2BB /* MTRDeviceTypeRevisionTests.m */; }; 3DA1A3552ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DA1A3522ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.h */; }; 3DA1A3562ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3DA1A3532ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.mm */; }; 3DA1A3582ABABF6A004F0BB9 /* MTRAsyncWorkQueueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DA1A3572ABABF69004F0BB9 /* MTRAsyncWorkQueueTests.m */; }; @@ -610,6 +614,10 @@ 3D84372F294984AF0070D20A /* command_completion_type.zapt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = command_completion_type.zapt; sourceTree = ""; }; 3D843754294AD25A0070D20A /* MTRCertificateInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRCertificateInfo.h; sourceTree = ""; }; 3D843755294AD25A0070D20A /* MTRCertificateInfo.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRCertificateInfo.mm; sourceTree = ""; }; + 3D9F2FBC2D10DB4F003CA2BB /* MTRProductIdentity.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRProductIdentity.h; sourceTree = ""; }; + 3D9F2FBD2D10DB4F003CA2BB /* MTRProductIdentity.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRProductIdentity.mm; sourceTree = ""; }; + 3D9F2FC02D10DCA2003CA2BB /* MTRProductIdentityTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MTRProductIdentityTests.m; sourceTree = ""; }; + 3D9F2FC22D10E207003CA2BB /* MTRDeviceTypeRevisionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MTRDeviceTypeRevisionTests.m; sourceTree = ""; }; 3DA1A3522ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRAsyncWorkQueue.h; sourceTree = ""; }; 3DA1A3532ABAB3B4004F0BB9 /* MTRAsyncWorkQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRAsyncWorkQueue.mm; sourceTree = ""; }; 3DA1A3572ABABF69004F0BB9 /* MTRAsyncWorkQueueTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTRAsyncWorkQueueTests.m; sourceTree = ""; }; @@ -1337,8 +1345,6 @@ 51D0B1362B618CC6006E3511 /* MTRServerAttribute.h */, 51D0B1372B618CC6006E3511 /* MTRServerAttribute.mm */, 514C79FF2B64223400DD6D7B /* MTRServerAttribute_Internal.h */, - 51D0B13A2B61B2F2006E3511 /* MTRDeviceTypeRevision.h */, - 51D0B13B2B61B2F2006E3511 /* MTRDeviceTypeRevision.mm */, 51D0B1262B617246006E3511 /* MTRServerEndpoint.h */, 51D0B1252B617246006E3511 /* MTRServerEndpoint.mm */, 514C7A002B64223400DD6D7B /* MTRServerEndpoint_Internal.h */, @@ -1542,6 +1548,8 @@ 51F522692AE70761000C4050 /* MTRDeviceTypeMetadata.h */, 5109E9B22CB8B5DF0006884B /* MTRDeviceType.h */, 5109E9B32CB8B5DF0006884B /* MTRDeviceType.mm */, + 51D0B13A2B61B2F2006E3511 /* MTRDeviceTypeRevision.h */, + 51D0B13B2B61B2F2006E3511 /* MTRDeviceTypeRevision.mm */, 5129BCFC26A9EE3300122DDF /* MTRError.h */, B2E0D7AB245B0B5C003C5B48 /* MTRError_Internal.h */, 51578AEA2D0B9DC0001716FF /* MTRError_Testable.h */, @@ -1572,6 +1580,8 @@ 998F287026D56940001846C6 /* MTRP256KeypairBridge.mm */, 2C8C8FBD253E0C2100797F05 /* MTRPersistentStorageDelegateBridge.h */, 2C8C8FBF253E0C2100797F05 /* MTRPersistentStorageDelegateBridge.mm */, + 3D9F2FBC2D10DB4F003CA2BB /* MTRProductIdentity.h */, + 3D9F2FBD2D10DB4F003CA2BB /* MTRProductIdentity.mm */, 514654482A72F9DF00904E61 /* MTRDemuxingStorage.mm */, 5146544A2A72F9F500904E61 /* MTRDemuxingStorage.h */, 51E95DF92A78443C00A434F0 /* MTRSessionResumptionStorageBridge.h */, @@ -1621,6 +1631,7 @@ 5AE6D4E327A99041001F2493 /* MTRDeviceTests.m */, 75B326A12BCF12E900E17C4E /* MTRDeviceConnectivityMonitorTests.m */, 5109E9B62CB8B83D0006884B /* MTRDeviceTypeTests.m */, + 3D9F2FC22D10E207003CA2BB /* MTRDeviceTypeRevisionTests.m */, 51D9CB0A2BA37DCE0049D6DB /* MTRDSTOffsetTests.m */, 3D0C484A29DA4FA0006D811F /* MTRErrorTests.m */, 51578AE82D0B9B1D001716FF /* MTRErrorMappingTests.m */, @@ -1630,6 +1641,7 @@ 5142E39729D377F000A206F0 /* MTROTAProviderTests.m */, 51742B4D29CB6B88009974FE /* MTRPairingTests.m */, 51E95DF72A78110900A434F0 /* MTRPerControllerStorageTests.m */, + 3D9F2FC02D10DCA2003CA2BB /* MTRProductIdentityTests.m */, 51D0B1292B61766F006E3511 /* MTRServerEndpointTests.m */, 3D4733AE2BDF1B80003DC19B /* MTRSetupPayloadTests.m */, 519498312A25581C00B3BABE /* MTRSetupPayloadInitializationTests.m */, @@ -1826,6 +1838,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 3D9F2FBE2D10DB4F003CA2BB /* MTRProductIdentity.h in Headers */, 51D0B1282B617246006E3511 /* MTRServerEndpoint.h in Headers */, 51565CB62A7B0D6600469F18 /* MTRDeviceControllerParameters.h in Headers */, 51565CB42A7AD78D00469F18 /* MTRDeviceControllerStorageDelegate.h in Headers */, @@ -2287,6 +2300,7 @@ CF3B63D12CA31E71003C1C87 /* MTROTAImageTransferHandler.mm in Sources */, 51D0B12F2B617800006E3511 /* MTRAccessGrant.mm in Sources */, 88E6C9482B6334ED001A1FE0 /* MTRMetrics.mm in Sources */, + 3D9F2FBF2D10DB4F003CA2BB /* MTRProductIdentity.mm in Sources */, 1ED276E226C5812A00547A89 /* MTRCluster.mm in Sources */, 9BFE5D512C6D3075007D4319 /* MTRDeviceController_XPC.mm in Sources */, 514A98B12CD98C5E000EF4FD /* MTRAttributeValueWaiter.mm in Sources */, @@ -2364,6 +2378,7 @@ 518D3F832AA132DC008E0007 /* MTRTestPerControllerStorage.m in Sources */, 51339B1F2A0DA64D00C798C1 /* MTRCertificateValidityTests.m in Sources */, 5173A47929C0E82300F67F48 /* MTRFabricInfoTests.m in Sources */, + 3D9F2FC12D10DCA2003CA2BB /* MTRProductIdentityTests.m in Sources */, 75B326A22BCF12E900E17C4E /* MTRDeviceConnectivityMonitorTests.m in Sources */, 5143851E2A65885500EDC8E6 /* MTRSwiftPairingTests.swift in Sources */, 75B0D01E2B71B47F002074DD /* MTRDeviceTestDelegate.m in Sources */, @@ -2377,6 +2392,7 @@ 51F9F9D52BF7A9EE00FEA0E2 /* MTRTestCase+ServerAppRunner.m in Sources */, 517BF3F3282B62CB00A8B7DB /* MTRCertificateTests.m in Sources */, 5142E39829D377F000A206F0 /* MTROTAProviderTests.m in Sources */, + 3D9F2FC32D10E207003CA2BB /* MTRDeviceTypeRevisionTests.m in Sources */, 51E0FC102ACBBF230001E197 /* MTRSwiftDeviceTests.swift in Sources */, 3D4733AF2BDF1B80003DC19B /* MTRSetupPayloadTests.m in Sources */, 5109E9B72CB8B83D0006884B /* MTRDeviceTypeTests.m in Sources */,