Actually commit the oAITests target wiring in project.pbxproj
The oAITests PBXNativeTarget (PBXContainerItemProxy, PBXTargetDependency,
XCBuildConfiguration with TEST_HOST/BUNDLE_LOADER, the "recommended
settings" changes accepted when the target was created -- DEAD_CODE_STRIPPING,
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED, STRING_CATALOG_GENERATE_SYMBOLS,
DEVELOPMENT_TEAM moved to project-level inheritance) was somehow never
actually staged in the very first "Add real oAITests target" commit
(8c7fb59) despite every xcodebuild test run since then depending on it
being present on disk. Every subsequent commit this session only staged
specific file paths (never oAI.xcodeproj again), so the gap went
unnoticed until a full `git status` review here.
Without this, anyone else pulling the branch (or a truly clean checkout
on this machine) would have all the .swift test files but no target to
compile them into -- xcodebuild test would fail to find oAITests at all.
Confirmed the diff is exactly the expected target-wiring content, nothing
unrelated or corrupted, before committing.
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// BackupServiceTests.swift
|
||||
// oAITests
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
|
||||
import Testing
|
||||
import Foundation
|
||||
@testable import oAI
|
||||
|
||||
@Suite("BackupService.decideFavoritesSync")
|
||||
struct BackupServiceFavoritesSyncTests {
|
||||
|
||||
private let now = Date(timeIntervalSince1970: 1_700_000_000)
|
||||
|
||||
@Test("No remote copy yet -- push local state")
|
||||
func noRemoteCopy() {
|
||||
let decision = BackupService.decideFavoritesSync(localIds: ["a", "b"], localUpdatedAt: "", remote: nil, now: now)
|
||||
#expect(decision == .pushLocal)
|
||||
}
|
||||
|
||||
@Test("Remote is newer -- apply it locally")
|
||||
func remoteNewer() {
|
||||
let remote = FavoritesPayload(updatedAt: "2026-02-01T00:00:00Z", ids: ["x", "y"])
|
||||
let decision = BackupService.decideFavoritesSync(
|
||||
localIds: ["a"],
|
||||
localUpdatedAt: "2026-01-01T00:00:00Z",
|
||||
remote: remote,
|
||||
now: now
|
||||
)
|
||||
#expect(decision == .applyRemote(ids: ["x", "y"], updatedAt: "2026-02-01T00:00:00Z"))
|
||||
}
|
||||
|
||||
@Test("Local is newer -- push local state, don't touch remote")
|
||||
func localNewer() {
|
||||
let remote = FavoritesPayload(updatedAt: "2026-01-01T00:00:00Z", ids: ["x"])
|
||||
let decision = BackupService.decideFavoritesSync(
|
||||
localIds: ["a"],
|
||||
localUpdatedAt: "2026-02-01T00:00:00Z",
|
||||
remote: remote,
|
||||
now: now
|
||||
)
|
||||
#expect(decision == .pushLocal)
|
||||
}
|
||||
|
||||
@Test("Tied timestamps with different sets -- merge via union and push")
|
||||
func tiedTimestampsDifferentSets() {
|
||||
let remote = FavoritesPayload(updatedAt: "", ids: ["b", "c"])
|
||||
let decision = BackupService.decideFavoritesSync(localIds: ["a", "b"], localUpdatedAt: "", remote: remote, now: now)
|
||||
guard case .mergeAndPush(let ids, let updatedAt) = decision else {
|
||||
Issue.record("Expected .mergeAndPush")
|
||||
return
|
||||
}
|
||||
#expect(ids == ["a", "b", "c"])
|
||||
#expect(!updatedAt.isEmpty) // stamped with `now`, not left blank
|
||||
}
|
||||
|
||||
@Test("Tied timestamps with identical sets -- no-op, already in sync")
|
||||
func tiedTimestampsIdenticalSets() {
|
||||
let remote = FavoritesPayload(updatedAt: "2026-01-01T00:00:00Z", ids: ["a", "b"])
|
||||
let decision = BackupService.decideFavoritesSync(
|
||||
localIds: ["a", "b"],
|
||||
localUpdatedAt: "2026-01-01T00:00:00Z",
|
||||
remote: remote,
|
||||
now: now
|
||||
)
|
||||
#expect(decision == .noop)
|
||||
}
|
||||
}
|
||||
|
||||
@Suite("BackupService.isBackupDue")
|
||||
struct BackupServiceAutoBackupTests {
|
||||
|
||||
private let now = Date(timeIntervalSince1970: 1_700_000_000)
|
||||
private let oneHour: TimeInterval = 3600
|
||||
|
||||
@Test("Manual frequency is never due")
|
||||
func manualNeverDue() {
|
||||
#expect(!BackupService.isBackupDue(frequency: "manual", lastBackupDate: nil, now: now))
|
||||
#expect(!BackupService.isBackupDue(frequency: "manual", lastBackupDate: now.addingTimeInterval(-1_000_000), now: now))
|
||||
}
|
||||
|
||||
@Test("No prior backup at all is always due, regardless of frequency")
|
||||
func noPriorBackupIsAlwaysDue() {
|
||||
#expect(BackupService.isBackupDue(frequency: "daily", lastBackupDate: nil, now: now))
|
||||
#expect(BackupService.isBackupDue(frequency: "weekly", lastBackupDate: nil, now: now))
|
||||
}
|
||||
|
||||
@Test("Daily: not due before 24 hours have passed, due at or after")
|
||||
func dailyThreshold() {
|
||||
let justUnder = now.addingTimeInterval(-(24 * oneHour - 1))
|
||||
let exactly = now.addingTimeInterval(-(24 * oneHour))
|
||||
#expect(!BackupService.isBackupDue(frequency: "daily", lastBackupDate: justUnder, now: now))
|
||||
#expect(BackupService.isBackupDue(frequency: "daily", lastBackupDate: exactly, now: now))
|
||||
}
|
||||
|
||||
@Test("Weekly: not due before 7 days have passed, due at or after")
|
||||
func weeklyThreshold() {
|
||||
let justUnder = now.addingTimeInterval(-(7 * 24 * oneHour - 1))
|
||||
let exactly = now.addingTimeInterval(-(7 * 24 * oneHour))
|
||||
#expect(!BackupService.isBackupDue(frequency: "weekly", lastBackupDate: justUnder, now: now))
|
||||
#expect(BackupService.isBackupDue(frequency: "weekly", lastBackupDate: exactly, now: now))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user