From 7ecbb05510b87b31c6f3f4f527dbbd8fcddb7caf Mon Sep 17 00:00:00 2001 From: Philippe Weidmann Date: Thu, 18 Jan 2024 09:40:00 +0100 Subject: [PATCH 1/2] feat: Identifiable collection --- .../Extensions/Collection+Identity.swift | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Sources/InfomaniakCore/Extensions/Collection+Identity.swift diff --git a/Sources/InfomaniakCore/Extensions/Collection+Identity.swift b/Sources/InfomaniakCore/Extensions/Collection+Identity.swift new file mode 100644 index 0000000..2250f28 --- /dev/null +++ b/Sources/InfomaniakCore/Extensions/Collection+Identity.swift @@ -0,0 +1,31 @@ +/* + Infomaniak Core - iOS + Copyright (C) 2023 Infomaniak Network SA + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +import Foundation +import SwiftUI + +@available(iOS 13.0, *) +public extension Collection where Element: Identifiable { + /// Compute a stable id for the given collection + func collectionId(baseId: AnyHashable? = nil) -> Int { + var hasher = Hasher() + hasher.combine(baseId) + forEach { hasher.combine($0.id) } + return hasher.finalize() + } +} From c82698045fc71727da9711ed51d9562a778c2b11 Mon Sep 17 00:00:00 2001 From: Philippe Weidmann Date: Thu, 18 Jan 2024 10:55:52 +0100 Subject: [PATCH 2/2] test: Add tests for UTCollection+Identity --- .../Extensions/UTCollection+Identity.swift | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 Tests/InfomaniakCoreTests/Extensions/UTCollection+Identity.swift diff --git a/Tests/InfomaniakCoreTests/Extensions/UTCollection+Identity.swift b/Tests/InfomaniakCoreTests/Extensions/UTCollection+Identity.swift new file mode 100644 index 0000000..0a17895 --- /dev/null +++ b/Tests/InfomaniakCoreTests/Extensions/UTCollection+Identity.swift @@ -0,0 +1,107 @@ +/* + Infomaniak Core - iOS + Copyright (C) 2023 Infomaniak Network SA + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +import InfomaniakCore +import XCTest + +extension Int: Identifiable { + public var id: Int { + return self + } +} + +@available(iOS 13.0, *) +final class UTCollectionIdentity: XCTestCase { + func testIntSameArraySameHash() { + // GIVEN + let lhsArray = [1, 2, 3, 4] + let rhsArray = [1, 2, 3, 4] + + // WHEN + let lhsId = lhsArray.collectionId() + let rhsId = rhsArray.collectionId() + + // THEN + XCTAssertEqual(lhsId, rhsId, "We expect the ids to be the same") + } + + func testIntSameArraySameHashWithBase() { + // GIVEN + let lhsArray = [1, 2, 3, 4] + let rhsArray = [1, 2, 3, 4] + + // WHEN + let lhsId = lhsArray.collectionId(baseId: 10) + let rhsId = rhsArray.collectionId(baseId: 10) + + // THEN + XCTAssertEqual(lhsId, rhsId, "We expect the ids to be the same") + } + + func testIntReversedArrayDifferentHash() { + // GIVEN + let lhsArray = [1, 2, 3, 4] + let rhsArray = [1, 2, 3, 4].reversed() + + // WHEN + let lhsId = lhsArray.collectionId() + let rhsId = rhsArray.collectionId() + + // THEN + XCTAssertNotEqual(lhsId, rhsId, "We expect the ids to not be the same") + } + + func testIntDifferentArrayDifferentHash() { + // GIVEN + let lhsArray = [1, 2, 3, 4] + let rhsArray = [1, 2, 3, 5] + + // WHEN + let lhsId = lhsArray.collectionId() + let rhsId = rhsArray.collectionId() + + // THEN + XCTAssertNotEqual(lhsId, rhsId, "We expect the ids to not be the same") + } + + func testIntDifferentArrayDifferentHashWithBase() { + // GIVEN + let lhsArray = [1, 2, 3, 4] + let rhsArray = [1, 2, 3, 5] + + // WHEN + let lhsId = lhsArray.collectionId(baseId: 10) + let rhsId = rhsArray.collectionId(baseId: 10) + + // THEN + XCTAssertNotEqual(lhsId, rhsId, "We expect the ids to not be the same") + } + + func testIntDifferentArrayDifferentHashWithDifferentBase() { + // GIVEN + let lhsArray = [1, 2, 3, 4] + let rhsArray = [1, 2, 3, 5] + + // WHEN + let lhsId = lhsArray.collectionId(baseId: 10) + let rhsId = rhsArray.collectionId(baseId: 11) + + // THEN + XCTAssertNotEqual(lhsId, rhsId, "We expect the ids to not be the same") + } +}