unit tests

This commit is contained in:
2026-05-24 20:40:25 +02:00
parent 857db7501d
commit 2346ca1b49
7 changed files with 427 additions and 12 deletions
@@ -0,0 +1,27 @@
import Foundation
@testable import Peered
final class InMemoryStorageProvider: StorageProvider {
private(set) var files: [String: Data] = [:]
func contentsOfDirectory(atPath path: String) throws -> [String] {
return files.keys.compactMap { filePath -> String? in
guard filePath.hasPrefix(path) else { return nil }
let remainder = String(filePath.dropFirst(path.count))
let stripped = remainder.hasPrefix("/") ? String(remainder.dropFirst()) : remainder
guard !stripped.isEmpty, !stripped.contains("/") else { return nil }
return stripped
}
}
@discardableResult
func createFile(
atPath path: String,
contents data: Data?,
attributes attr: [FileAttributeKey: Any]?
) -> Bool {
files[path] = data ?? Data()
return true
}
}
@@ -0,0 +1,28 @@
import Foundation
import Testing
@testable import Peered
@Suite
struct NoteContentCodableTests {
@Test("encode → decode")
func coding() throws {
let original = NoteInvitation.NoteContent(
title: "My note", noteSnapshot: "Note Sample Snapshot")
let data = try JSONEncoder().encode(original)
let decoded = try JSONDecoder().decode(NoteInvitation.NoteContent.self, from: data)
#expect(decoded.title == original.title)
#expect(decoded.noteSnapshot == original.noteSnapshot)
}
@Test
func containsExpectedKeys() throws {
let content = NoteInvitation.NoteContent(title: "Titlee", noteSnapshot: "Snapshott")
let data = try JSONEncoder().encode(content)
let json = try #require(try? JSONSerialization.jsonObject(with: data) as? [String: String])
#expect(json["title"] == "Titlee")
#expect(json["noteSnapshot"] == "Snapshott")
}
}
@@ -0,0 +1,88 @@
import MultipeerConnectivity
import Testing
@testable import Peered
extension NoteInvitation {
fileprivate init(handler: @escaping (Bool) -> Void) {
self.init(
invitatorID: .init(
displayName: "host"
),
note: .init(title: "Shared note", noteSnapshot: "Snapshot"),
invitationHandler: handler
)
}
}
@Suite
struct NoteInvitationTests {
@Test
func acceptCallsHandlerWithTrue() {
var received: Bool? = nil
var invitation = NoteInvitation { received = $0 }
invitation.accept()
#expect(received == true)
}
@Test
func declineCallsHandlerWithFalse() {
var received: Bool? = nil
var invitation = NoteInvitation { received = $0 }
invitation.decline()
#expect(received == false)
}
@Test
func acceptIsIdempotent() {
var callCount = 0
var invitation = NoteInvitation { _ in callCount += 1 }
invitation.accept()
invitation.accept()
#expect(callCount == 1)
}
@Test
func declineIsIdempotent() {
var callCount = 0
var invitation = NoteInvitation { _ in callCount += 1 }
invitation.decline()
invitation.decline()
#expect(callCount == 1)
}
@Test
func declineAfterAcceptIsNoOp() {
var callCount = 0
var invitation = NoteInvitation { _ in callCount += 1 }
invitation.accept()
invitation.decline()
#expect(callCount == 1)
}
@Test
func noteNameReturnsTitle() {
let invitation = NoteInvitation { _ in }
#expect(invitation.noteName == "Shared note")
}
@Test
func idIsInvitatorPeerID() {
let peerID = MCPeerID(displayName: "host")
let invitation = NoteInvitation(
invitatorID: peerID,
note: .init(title: "T", noteSnapshot: "S")
)
#expect(invitation.id == peerID)
}
}
@@ -0,0 +1,37 @@
import Foundation
import Testing
@testable import Peered
@Suite
struct NoteMessageCodableTests {
@Test
func encodesToJSON() throws {
let message = NoteMessage(senderID: "host", content: "Content")
let data = try JSONEncoder().encode(message)
let json = try #require(try? JSONSerialization.jsonObject(with: data) as? [String: String])
#expect(json["senderID"] == "host")
#expect(json["content"] == "Content")
}
@Test
func decodesFromJSON() throws {
let json = #"{"senderID":"host","content":"contentt"}"#
let data = try #require(json.data(using: .utf8))
let message = try JSONDecoder().decode(NoteMessage.self, from: data)
#expect(message.senderID == "host")
#expect(message.content == "contentt")
}
@Test("encode → decode")
func coding() throws {
let original = NoteMessage(senderID: "host", content: "coding test")
let data = try JSONEncoder().encode(original)
let decoded = try JSONDecoder().decode(NoteMessage.self, from: data)
#expect(decoded.senderID == original.senderID)
#expect(decoded.content == original.content)
}
}
@@ -0,0 +1,74 @@
import Foundation
import Testing
@testable import Peered
@Suite
struct NotesStorageTests {
private func makeStorage(root: URL = URL(filePath: "/test")) -> (
NotesStorage, InMemoryStorageProvider
) {
let provider = InMemoryStorageProvider()
let storage = NotesStorage(storageProvider: provider, rootDirectory: root)
return (storage, provider)
}
@Test
func loadNotesReturnsEmptyArrayWhenNoFiles() {
let (storage, _) = makeStorage()
let notes = storage.loadNotes()
#expect(notes.isEmpty)
}
@Test
func createNoteCreatesFile() {
let root = URL(filePath: "/test")
let (storage, provider) = makeStorage(root: root)
storage.createNote(name: "My note")
#expect(!provider.files.isEmpty)
}
@Test
func loadNotesReturnCreatedNote() {
let root = URL(filePath: "/test")
let (storage, provider) = makeStorage(root: root)
let filePath = root.appendingPathComponent("Note").path
provider.createFile(atPath: filePath, contents: Data(), attributes: nil)
let notes = storage.loadNotes()
#expect(notes.count == 1)
#expect(notes.first?.name == "Note")
}
@Test
func createNoteDeduplicatesNames() {
let root = URL(filePath: "/test")
let (storage, provider) = makeStorage(root: root)
let existingPath = root.appendingPathComponent("Note").path
provider.createFile(atPath: existingPath, contents: Data(), attributes: nil)
storage.createNote(name: "Note")
#expect(provider.files.count == 2)
let paths = provider.files.keys
#expect(paths.contains(where: { $0.contains("Note 1") }))
}
@Test
func createNoteTwiceCreatesTwoFiles() {
let root = URL(filePath: "/test")
let (storage, _) = makeStorage(root: root)
storage.createNote(name: "Note")
storage.createNote(name: "Note")
let notes = storage.loadNotes()
#expect(notes.count == 2)
}
}