diff --git a/bitchat/Utils/Color+Peer.swift b/bitchat/Utils/Color+Peer.swift index e2ab3a1566..2a5a0d0aca 100644 --- a/bitchat/Utils/Color+Peer.swift +++ b/bitchat/Utils/Color+Peer.swift @@ -10,12 +10,22 @@ import SwiftUI extension Color { private static var peerColorCache: [String: Color] = [:] - + + #if DEBUG + /// Counts cache-miss computations; exposed only so regression tests can + /// verify a repeated seed hits the cache instead of recomputing. + static var _peerColorComputeCountForTesting = 0 + #endif + init(peerSeed: String, isDark: Bool) { let cacheKey = peerSeed + (isDark ? "|dark" : "|light") if let cached = Self.peerColorCache[cacheKey] { self = cached + return } + #if DEBUG + Self._peerColorComputeCountForTesting += 1 + #endif let h = peerSeed.djb2() var hue = Double(h % 1000) / 1000.0 let orange = 30.0 / 360.0 diff --git a/bitchatTests/Utils/ColorPeerTests.swift b/bitchatTests/Utils/ColorPeerTests.swift new file mode 100644 index 0000000000..023459ee01 --- /dev/null +++ b/bitchatTests/Utils/ColorPeerTests.swift @@ -0,0 +1,45 @@ +// +// ColorPeerTests.swift +// bitchatTests +// +// Tests for Color(peerSeed:isDark:) caching +// + +import Testing +import SwiftUI +@testable import bitchat + +struct ColorPeerTests { + + @Test func repeatedSeedHitsCacheInsteadOfRecomputing() { + let seed = "cache-hit-\(UUID().uuidString)" + + let before = Color._peerColorComputeCountForTesting + let first = Color(peerSeed: seed, isDark: true) + let afterFirst = Color._peerColorComputeCountForTesting + let second = Color(peerSeed: seed, isDark: true) + let afterSecond = Color._peerColorComputeCountForTesting + + #expect(afterFirst == before + 1) + #expect(afterSecond == afterFirst) + #expect(first == second) + } + + @Test func differentAppearanceForSameSeedIsNotCachedTogether() { + let seed = "appearance-\(UUID().uuidString)" + + let before = Color._peerColorComputeCountForTesting + _ = Color(peerSeed: seed, isDark: true) + _ = Color(peerSeed: seed, isDark: false) + let after = Color._peerColorComputeCountForTesting + + #expect(after == before + 2) + } + + @Test func sameSeedProducesSameColor() { + let seed = "deterministic-\(UUID().uuidString)" + let a = Color(peerSeed: seed, isDark: false) + let b = Color(peerSeed: seed, isDark: false) + #expect(a == b) + } +}