A code-coverage pass found two source files at 0% in the standing suite (covered only by opt-in gates) and one large under-covered file: - XSDParserUnion.swift (Document(composing:), the multi-document union, #161) was exercised only by the opt-in XSTS harness, so plain `swift test` never ran multi-document composition. SchemaComposingTests now covers it via a cross-document substitution group (0% to 92% line). - XSLTCollation.swift (language-tailored xsl:sort orders) was unexercised by any standing test. XSLTCollationTests covers the Polish/Russian tables and the fallback (0% to 88% line). - StreamingDecoder.swift (byte-at-a-time CJK/UTF decode) had the streaming/split path under-tested. StreamingDecoderTests feeds bytes one at a time through GBK, Big5, Shift_JIS, EUC-KR, EUC-JP, GB18030, the UTF-16/32 BOM paths, and a malformed sequence (48% to 80% line, 37% to 72% region). Expected scalars were taken from the decoder and pinned. Test-only; +10 tests; full suite green (1568).
47 lines
2.1 KiB
Swift
47 lines
2.1 KiB
Swift
import Testing
|
||
@testable import PureXML
|
||
|
||
/// Language-tailored `xsl:sort` collation orders (XSLTCollation.swift). These tables
|
||
/// were previously exercised only through the XSLT conformance golds; this gives them
|
||
/// standing coverage so `swift test` verifies the tailored orders directly.
|
||
@Suite("XSLT language collation (xsl:sort lang)")
|
||
struct XSLTCollationTests {
|
||
private typealias Collation = PureXML.XSLT.Collation
|
||
|
||
@Test("Polish ranks Ł between L and M, case-folded")
|
||
func test_polish() throws {
|
||
let ranks = try #require(Collation.table(for: "pl"))
|
||
// L (U+004C) < Ł (U+0141) < M, the tailored order; under plain Unicode Ł
|
||
// would sort after every ASCII letter, so this is the meaningful difference.
|
||
#expect(Collation.compare("Lis", "Łoś", ranks) < 0)
|
||
#expect(Collation.compare("Łoś", "Maj", ranks) < 0)
|
||
// Diacritic letters interleave after their base: Ą after A, Ć after C.
|
||
#expect(Collation.compare("Ananas", "Ćma", ranks) < 0)
|
||
// Case-folded: lowercase ł shares Ł's rank, so it still sorts before m.
|
||
#expect(Collation.compare("łoś", "maj", ranks) < 0)
|
||
}
|
||
|
||
@Test("Russian ranks Ё after Е, accepts a lang subtag")
|
||
func test_russian() throws {
|
||
// The primary subtag is honored, so `ru-RU` resolves to the Russian table.
|
||
let ranks = try #require(Collation.table(for: "ru-RU"))
|
||
#expect(Collation.compare("Е", "Ё", ranks) < 0)
|
||
#expect(Collation.compare("Ё", "Ж", ranks) < 0)
|
||
}
|
||
|
||
@Test("an untabled language has no tailored order (nil)")
|
||
func test_fallbackLanguages() {
|
||
#expect(Collation.table(for: "en") == nil)
|
||
#expect(Collation.table(for: "fr-CA") == nil)
|
||
#expect(Collation.table(for: "") == nil)
|
||
}
|
||
|
||
@Test("compare orders by length then code point when ranks tie")
|
||
func test_tieBreaks() throws {
|
||
let ranks = try #require(Collation.table(for: "pl"))
|
||
// A prefix sorts before the longer string sharing it.
|
||
#expect(Collation.compare("Lis", "Lisek", ranks) < 0)
|
||
#expect(Collation.compare("Lis", "Lis", ranks) == 0)
|
||
}
|
||
}
|