mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-24 23:45:18 +00:00
Periphery 3.7.4 audit of both schemes (macOS + iOS, intersected so platform-specific code is never touched), with test targets indexed and the share extension built. 277 dead declarations removed or demoted: dead forwarding wrappers (ChatViewModel+Nostr/+PrivateChat), removed- feature remnants (autocomplete command suggestions, back-swipe tuning, MediaSendError, GeohashParticipantTracker), unused Tor dormancy bindings, assign-only properties, unused parameters (renamed to _), and redundant public accessibility. 13 orphaned localization keys deleted across all 29 locales (old pre-#1392 location-notes UI, app_info warnings). Two real tests were flagged as unused because they never ran: Swift Testing methods missing @Test (NostrProtocolTests. testAckRoundTripNIP44V2_Delivered, NotificationStreamAssemblerTests. testAssemblesCompressedLargeFrame). Re-armed both; they pass. Deliberately kept, now recorded in .periphery.baseline.json: iOS-only code invisible to the CI macOS scan, C FFI signatures, keep-alive NWPathMonitor reference, InboundEventKey.eventID (dedup semantics), wifiBulk capability bit (reserved for Wi-Fi bulk work, used by BitFoundation package tests), and the String secureClear cluster (exercised by package tests). New: .periphery.yml config and an advisory Dead Code CI job (mirrors the SwiftLint precedent from #1361) that fails on findings not in the committed baseline. Verified: full macOS app suite, BitFoundation (119) and BitLogger (13) package tests green; periphery scan --strict exits clean. Co-authored-by: jack <jackjackbits@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
133 lines
4.0 KiB
Swift
133 lines
4.0 KiB
Swift
//
|
|
// TestHelpers.swift
|
|
// bitchatTests
|
|
//
|
|
// This is free and unencumbered software released into the public domain.
|
|
// For more information, see <https://unlicense.org>
|
|
//
|
|
|
|
import Foundation
|
|
import CryptoKit
|
|
import BitFoundation
|
|
@testable import bitchat
|
|
|
|
final class TestHelpers {
|
|
|
|
// MARK: - Message Creation
|
|
|
|
static func createTestMessage(
|
|
content: String = TestConstants.testMessage1,
|
|
sender: String = TestConstants.testNickname1,
|
|
senderPeerID: PeerID = PeerID(str: UUID().uuidString),
|
|
isPrivate: Bool = false,
|
|
recipientNickname: String? = nil,
|
|
mentions: [String]? = nil
|
|
) -> BitchatMessage {
|
|
return BitchatMessage(
|
|
id: UUID().uuidString,
|
|
sender: sender,
|
|
content: content,
|
|
timestamp: Date(),
|
|
isRelay: false,
|
|
originalSender: nil,
|
|
isPrivate: isPrivate,
|
|
recipientNickname: recipientNickname,
|
|
senderPeerID: senderPeerID,
|
|
mentions: mentions
|
|
)
|
|
}
|
|
|
|
static func createTestPacket(
|
|
type: UInt8 = 0x01,
|
|
senderID: PeerID = PeerID(str: UUID().uuidString),
|
|
recipientID: PeerID? = nil,
|
|
payload: Data = Data("test payload".utf8),
|
|
signature: Data? = nil,
|
|
ttl: UInt8 = 3
|
|
) -> BitchatPacket {
|
|
return BitchatPacket(
|
|
type: type,
|
|
senderID: Data(senderID.id.utf8),
|
|
recipientID: recipientID?.id.data(using: .utf8),
|
|
timestamp: UInt64(Date().timeIntervalSince1970 * 1000),
|
|
payload: payload,
|
|
signature: signature,
|
|
ttl: ttl
|
|
)
|
|
}
|
|
|
|
// MARK: - Data Generation
|
|
|
|
static func generateRandomData(length: Int) -> Data {
|
|
var data = Data(count: length)
|
|
_ = data.withUnsafeMutableBytes { bytes in
|
|
SecRandomCopyBytes(kSecRandomDefault, length, bytes.baseAddress!)
|
|
}
|
|
return data
|
|
}
|
|
|
|
// MARK: - Async Helpers
|
|
|
|
static func waitFor(_ condition: @escaping () -> Bool, timeout: TimeInterval = TestConstants.defaultTimeout) async throws {
|
|
let start = Date()
|
|
while !condition() {
|
|
if Date().timeIntervalSince(start) > timeout {
|
|
throw TestError.timeout
|
|
}
|
|
try await sleep(0.01)
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
static func waitUntil(
|
|
_ condition: @escaping () -> Bool,
|
|
timeout: TimeInterval = TestConstants.defaultTimeout,
|
|
pollInterval: TimeInterval = 0.01
|
|
) async -> Bool {
|
|
let start = Date()
|
|
while !condition() {
|
|
if Date().timeIntervalSince(start) > timeout {
|
|
return condition()
|
|
}
|
|
try? await sleep(pollInterval)
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
|
|
enum TestError: Error {
|
|
case timeout
|
|
}
|
|
|
|
// MARK: - Private chat seeding (ConversationStore migration)
|
|
|
|
extension ChatViewModel {
|
|
/// Test-only replacement for the deleted `privateChats` setter: seeds a
|
|
/// peer's chat through the single-writer `ConversationStore` intents
|
|
/// (upsert keeps re-seeding with updated copies working the way the old
|
|
/// dictionary assignment did).
|
|
@MainActor
|
|
func seedPrivateChat(_ messages: [BitchatMessage], for peerID: PeerID) {
|
|
_ = conversations.conversation(for: .directPeer(peerID))
|
|
for message in messages {
|
|
conversations.upsertByID(message, in: .directPeer(peerID))
|
|
}
|
|
}
|
|
|
|
/// Test-only replacement for the deleted `messages` setter: seeds a
|
|
/// public channel's conversation through the single-writer
|
|
/// `ConversationStore` intents (upsert keeps re-seeding with updated
|
|
/// copies working the way the old array assignment did).
|
|
@MainActor
|
|
func seedPublicMessages(_ messages: [BitchatMessage], for channel: ChannelID = .mesh) {
|
|
for message in messages {
|
|
conversations.upsertByID(message, in: ConversationID(channelID: channel))
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func sleep(_ seconds: TimeInterval) async throws {
|
|
try await Task.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
|
|
}
|