PureXML/Tests/XSLTCollationTests.swift
Mihaela Mihaljevic bd0b47a535 test(schema,xslt,parsing): standing coverage for the gaps a coverage run found
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).
2026-06-22 16:16:32 +02:00

47 lines
2.1 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}
}