PureYAMLStreaming/Tests/PureYAMLStreamingTests/DocumentScannerTestSupport.swift
Mihaela Mihaljevic b4253fd289 fix: drive document boundary scanning off PureYAML's token scanner
Replace the line-based --- heuristic with a scan over PureYAML's
resumable token scanner, so a --- inside a quoted scalar can no longer
misfire as a document boundary and directives stay attached to the
document they introduce. Add a differential suite that checks the new
scanner against the old line-based reference across generated streams
and the full Geekbench corpus.
2026-07-26 20:59:39 +02:00

55 lines
1.8 KiB
Swift

import Foundation
import PureYAML
@testable import PureYAMLStreaming
/// The integer stored under `key` when `value` is a mapping, or nil.
func intValue(_ key: String, in value: PureYAML.Model.Value) -> Int? {
guard case let .mapping(mapping) = value,
case let .int(number)? = mapping[key]
else {
return nil
}
return number
}
/// Splits `input` into chunks of `size` Unicode scalars, so a chunk boundary
/// can land anywhere: mid-line, mid-token, and mid-grapheme.
func scalarChunks(_ input: String, size: Int) -> [String] {
precondition(size > 0)
let scalars = Array(input.unicodeScalars)
var chunks: [String] = []
var index = 0
while index < scalars.count {
let end = min(index + size, scalars.count)
chunks.append(String(String.UnicodeScalarView(scalars[index ..< end])))
index = end
}
return chunks
}
/// All document sources the rewired scanner emits for `input` fed in
/// `chunkSize`-scalar chunks, in emission order.
func rewiredSegments(_ input: String, chunkSize: Int) throws -> [String] {
var scanner = PureYAMLStreaming.ResumableDocumentScanner()
var segments: [String] = []
for chunk in scalarChunks(input, size: chunkSize) {
segments += try scanner.consume(chunk)
}
segments += try scanner.finish()
return segments
}
/// All document sources the frozen line-based reference emits for `input` fed
/// in `chunkSize`-scalar chunks, in emission order.
func referenceSegments(_ input: String, chunkSize: Int) throws -> [String] {
var scanner = LineBasedReferenceScanner()
var segments: [String] = []
for chunk in scalarChunks(input, size: chunkSize) {
segments += try scanner.consume(chunk)
}
if let final = try scanner.finish() {
segments.append(final)
}
return segments
}