From 09123a4696d13ac372ea62dfdd31a6c732893915 Mon Sep 17 00:00:00 2001 From: Julian Date: Thu, 12 Mar 2026 23:06:27 -0700 Subject: [PATCH] test: add missing model and error code test coverage fix: decode unknown DocumentationKind values as nil --- .../XCDocs/Models/DocumentationEntry.swift | 9 ++++ Tests/XCDocsTests/BridgeErrorTests.swift | 2 +- Tests/XCDocsTests/ModelTests.swift | 45 +++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/Sources/XCDocs/Models/DocumentationEntry.swift b/Sources/XCDocs/Models/DocumentationEntry.swift index 7b307ef..8c0aeba 100644 --- a/Sources/XCDocs/Models/DocumentationEntry.swift +++ b/Sources/XCDocs/Models/DocumentationEntry.swift @@ -33,4 +33,13 @@ public struct DocumentationEntry: Codable, Hashable, Identifiable, Sendable { self.title = title self.content = content } + + public init(from decoder: any Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.id = try container.decode(String.self, forKey: .id) + self.framework = try container.decodeIfPresent(String.self, forKey: .framework) + self.kind = try? container.decodeIfPresent(DocumentationKind.self, forKey: .kind) + self.title = try container.decodeIfPresent(String.self, forKey: .title) + self.content = try container.decodeIfPresent(String.self, forKey: .content) + } } diff --git a/Tests/XCDocsTests/BridgeErrorTests.swift b/Tests/XCDocsTests/BridgeErrorTests.swift index d3762e3..d1f5de0 100644 --- a/Tests/XCDocsTests/BridgeErrorTests.swift +++ b/Tests/XCDocsTests/BridgeErrorTests.swift @@ -25,7 +25,7 @@ struct BridgeErrorTests { func formatsDescriptionForAllErrorCodes() { let codes: [BridgeErrorCode] = [ .frameworkUnavailable, .classUnavailable, .selectorUnavailable, .assetNotFound, .invalidResponse, - .invalidEmbedding, .operationFailed, .searchFailed, .timeout, + .invalidEmbedding, .operationFailed, .invalidScore, .searchFailed, .timeout, ] for code in codes { diff --git a/Tests/XCDocsTests/ModelTests.swift b/Tests/XCDocsTests/ModelTests.swift index 4e639fc..25c4085 100644 --- a/Tests/XCDocsTests/ModelTests.swift +++ b/Tests/XCDocsTests/ModelTests.swift @@ -39,6 +39,24 @@ struct ModelTests { guard #available(macOS 26, *) else { return } assertStableIdentities() } + + @Test + func documentationEntryDecodesUnknownKindAsNil() throws { + guard #available(macOS 26, *) else { return } + try assertUnknownKindDecodesAsNil() + } + + @Test + func searchResultWithNaNScoreThrowsOnJSONEncode() throws { + guard #available(macOS 26, *) else { return } + assertNaNScoreThrowsOnEncode() + } + + @Test + func searchResultWithInfinityScoreThrowsOnJSONEncode() throws { + guard #available(macOS 26, *) else { return } + assertInfinityScoreThrowsOnEncode() + } } @available(macOS 26, *) @@ -147,6 +165,33 @@ private func assertStableIdentities() { #expect(result.id == entry.id) } +@available(macOS 26, *) +private func assertUnknownKindDecodesAsNil() throws { + let json = """ + {"id":"/doc/X","framework":null,"kind":"unknownKind","title":null,"content":null} + """ + let entry = try JSONDecoder().decode(DocumentationEntry.self, from: Data(json.utf8)) + #expect(entry.kind == nil) +} + +@available(macOS 26, *) +private func assertNaNScoreThrowsOnEncode() { + let result = SearchResult( + score: .nan, + entry: DocumentationEntry(id: "/doc/X", framework: nil, kind: nil, title: nil, content: nil) + ) + #expect(throws: EncodingError.self) { try JSONEncoder().encode(result) } +} + +@available(macOS 26, *) +private func assertInfinityScoreThrowsOnEncode() { + let result = SearchResult( + score: .infinity, + entry: DocumentationEntry(id: "/doc/X", framework: nil, kind: nil, title: nil, content: nil) + ) + #expect(throws: EncodingError.self) { try JSONEncoder().encode(result) } +} + private func assertRoundTrip(_ value: T) throws { let data = try JSONEncoder().encode(value) let decoded = try JSONDecoder().decode(T.self, from: data)