summaryrefslogtreecommitdiff
path: root/SoraTests
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-23 22:02:59 -0800
committerFuwn <[email protected]>2026-02-23 22:02:59 -0800
commit7904b2366a28fca2585b5f5ec0588412e10f0c94 (patch)
treee57236200c0f377d0d06f1c90231551f7be3dbed /SoraTests
parentfeat: localize accessibility fallback and value strings (diff)
downloadsora-testing-main.tar.xz
sora-testing-main.zip
perf: cache danbooru page token floor and reuse search-history payloadsHEADmain
Diffstat (limited to 'SoraTests')
-rw-r--r--SoraTests/SettingsManagerSyncTests.swift77
-rw-r--r--SoraTests/ViewDerivedDataTests.swift63
2 files changed, 140 insertions, 0 deletions
diff --git a/SoraTests/SettingsManagerSyncTests.swift b/SoraTests/SettingsManagerSyncTests.swift
index 50106dc..8ed9d83 100644
--- a/SoraTests/SettingsManagerSyncTests.swift
+++ b/SoraTests/SettingsManagerSyncTests.swift
@@ -91,6 +91,83 @@ final class SettingsManagerSyncTests: XCTestCase {
)
}
+ func testSearchHistoryMutationPathReusesSortedPayloadAndAvoidsInlineResort() throws {
+ let source = try loadSource(at: "Sora/Data/Settings/SettingsManager.swift")
+ let searchHistorySetterSection = try extractFunction(
+ named: "var searchHistory: [BooruSearchQuery]",
+ from: source
+ )
+ let updateSearchHistorySection = try extractFunction(
+ named: "func updateSearchHistory(",
+ from: source
+ )
+ let normalizedSetterSection = strippingCommentsAndStrings(from: searchHistorySetterSection)
+ let normalizedUpdateSection = strippingCommentsAndStrings(from: updateSearchHistorySection)
+ let setterSortedHistoryDeclarationCount = tokenCount(
+ matching: #"\blet\s+sortedSearchHistory\s*="#,
+ in: normalizedSetterSection
+ )
+ let setterInlineSortClosureCount = tokenCount(
+ matching: #"syncableData\s*\([\s\S]*?\)\s*\{\s*\$0\s*\.\s*sorted"#,
+ in: normalizedSetterSection
+ )
+ let setterPreEncodedForwardCount = tokenCount(
+ matching: #"syncableData\s*\([\s\S]*?\bencodedData\s*:"#,
+ in: normalizedSetterSection
+ )
+
+ let updateSortedHistoryDeclarationCount = tokenCount(
+ matching: #"\blet\s+sortedSearchHistory\s*="#,
+ in: normalizedUpdateSection
+ )
+ let updateInlineSortClosureCount = tokenCount(
+ matching: #"syncableData\s*\([\s\S]*?\)\s*\{\s*\$0\s*\.\s*sorted"#,
+ in: normalizedUpdateSection
+ )
+ let updatePreEncodedForwardCount = tokenCount(
+ matching: #"syncableData\s*\([\s\S]*?\bencodedData\s*:"#,
+ in: normalizedUpdateSection
+ )
+
+ // swiftlint:disable:next prefer_nimble
+ XCTAssertGreaterThan(
+ setterSortedHistoryDeclarationCount,
+ 0,
+ "searchHistory setter should precompute sorted values once."
+ )
+ // swiftlint:disable:next prefer_nimble
+ XCTAssertEqual(
+ setterInlineSortClosureCount,
+ 0,
+ "searchHistory setter should avoid inline resorting inside syncableData."
+ )
+ // swiftlint:disable:next prefer_nimble
+ XCTAssertGreaterThan(
+ setterPreEncodedForwardCount,
+ 0,
+ "searchHistory setter should forward a pre-encoded payload to syncableData."
+ )
+
+ // swiftlint:disable:next prefer_nimble
+ XCTAssertGreaterThan(
+ updateSortedHistoryDeclarationCount,
+ 0,
+ "updateSearchHistory should precompute sorted values once."
+ )
+ // swiftlint:disable:next prefer_nimble
+ XCTAssertEqual(
+ updateInlineSortClosureCount,
+ 0,
+ "updateSearchHistory should avoid inline resorting inside syncableData."
+ )
+ // swiftlint:disable:next prefer_nimble
+ XCTAssertGreaterThan(
+ updatePreEncodedForwardCount,
+ 0,
+ "updateSearchHistory should forward a pre-encoded payload to syncableData."
+ )
+ }
+
func testBatchedSyncPathGuardsUnchangedPayloadWrites() throws {
let source = try loadSource(at: "Sora/Data/Settings/SettingsManager.swift")
let triggerSyncSection = try extractFunction(
diff --git a/SoraTests/ViewDerivedDataTests.swift b/SoraTests/ViewDerivedDataTests.swift
index 6a27667..d19b51a 100644
--- a/SoraTests/ViewDerivedDataTests.swift
+++ b/SoraTests/ViewDerivedDataTests.swift
@@ -872,6 +872,69 @@ final class ViewDerivedDataTests: XCTestCase { // swiftlint:disable:this type_b
)
}
+ func testBooruManagerDanbooruPaginationCachesMinimumPostIDForCursorToken() throws {
+ let source = try loadSource(at: "Sora/Data/Booru/BooruManager.swift")
+ let pageTokenFunctionSection = try extractFunction(
+ named: "private func danbooruPageToken(for page: Int, tags: [String]) -> String",
+ from: source
+ )
+ let updatePostsSection = try extractFunction(
+ named: "private func updatePosts(_ newPosts: [BooruPost], replace: Bool)",
+ from: source
+ )
+ let cachedMinimumPostIDStorageCount = tokenCount(
+ matching: #"private\s+var\s+cachedMinimumPostID:\s*Int\?"#,
+ in: source
+ )
+ let cachedTokenGuardCount = tokenCount(
+ matching: #"guard\s+let\s+minimumPostID\s*=\s*cachedMinimumPostID"#,
+ in: pageTokenFunctionSection
+ )
+ let directPostsMinScanCount = tokenCount(
+ matching: #"posts\s*\.\s*lazy\s*\.\s*compactMap\s*\(\s*\{\s*Int\(\$0\.id\)\s*\}\s*\)\s*\.\s*min"#,
+ in: pageTokenFunctionSection
+ )
+ let cacheInvalidationOnReplaceCount = tokenCount(
+ matching: #"cachedMinimumPostID\s*=\s*nil"#,
+ in: updatePostsSection
+ )
+ let cacheRefreshCount = tokenCount(
+ matching: #"cachedMinimumPostID\s*=\s*min\("#,
+ in: updatePostsSection
+ )
+
+ // swiftlint:disable:next prefer_nimble
+ XCTAssertGreaterThan(
+ cachedMinimumPostIDStorageCount,
+ 0,
+ "BooruManager should store a cached minimum post ID for Danbooru pagination."
+ )
+ // swiftlint:disable:next prefer_nimble
+ XCTAssertGreaterThan(
+ cachedTokenGuardCount,
+ 0,
+ "Danbooru page token generation should use cached minimum post ID."
+ )
+ // swiftlint:disable:next prefer_nimble
+ XCTAssertEqual(
+ directPostsMinScanCount,
+ 0,
+ "Danbooru page token generation should avoid rescanning all posts for minimum ID."
+ )
+ // swiftlint:disable:next prefer_nimble
+ XCTAssertGreaterThan(
+ cacheInvalidationOnReplaceCount,
+ 0,
+ "Replacing posts should invalidate cached Danbooru minimum post ID."
+ )
+ // swiftlint:disable:next prefer_nimble
+ XCTAssertGreaterThan(
+ cacheRefreshCount,
+ 0,
+ "Appending posts should refresh cached Danbooru minimum post ID incrementally."
+ )
+ }
+
func testBooruManagerDoesNotForceClientSidePostResort() throws {
let source = try loadSource(at: "Sora/Data/Booru/BooruManager.swift")
let retrySection = try extractFunction(