PureYAML/Tests/SignedOctalLookalikeTests.swift
Mihaela Mihaljevic d2421aa0ce fix(parsing): a zero followed by a sign is text, not an octal integer
Int(_, radix:) accepts a sign, so 0-3 (a CPU range, a port range) was read as the integer -3, and 0x-1, 0b-1 and 0o-1 as negative numbers. After a radix prefix only digits may follow. Octal, hex, binary and signed integers read as before.
2026-11-02 18:25:06 +01:00

26 lines
1.4 KiB
Swift

@testable import PureYAML
import Testing
/// A plain scalar that starts with `0` is an octal integer only when everything after the `0` is octal digits. A sign after the leading zero makes it text:
/// `0-3` is the range "0 to 3" (a CPU set, a port range), not minus three.
@Suite("Plain scalars that begin with a zero")
struct SignedOctalLookalikeTests {
@Test("A zero followed by a sign is text", arguments: ["0-3", "0-15", "0+1", "00-1", "0x-1", "0b-1", "0o-1"])
func test_signAfterTheLeadingZeroIsText(_ scalar: String) throws {
#expect(try PureYAML.parse("key: \(scalar)\n") == .mapping(.init([.init(key: "key", value: .string(scalar))])))
}
@Test("Octal, hexadecimal, binary and signed integers stay integers", arguments: [
("0755", 493), ("0", 0), ("-0", 0), ("0x1F", 31), ("0b101", 5), ("0o17", 15), ("-12", -12), ("+7", 7), ("-0755", -493),
])
func test_integersAreStillIntegers(_ scalar: String, _ expected: Int) throws {
#expect(try PureYAML.parse("key: \(scalar)\n") == .mapping(.init([.init(key: "key", value: .int(expected))])))
}
@Test("A range written with a leading zero survives a round trip", arguments: ["0-3", "0-15"])
func test_rangeRoundTrips(_ scalar: String) throws {
let value = PureYAML.Model.Value.mapping(.init([.init(key: "cpuset", value: .string(scalar))]))
#expect(try PureYAML.parse(PureYAML.dump(value)) == value)
}
}