Control characters, DEL, the C1 controls, U+2028, U+2029, U+FEFF, U+FFFE and U+FFFF were written as they are, where the reader refused them, folded U+0085, U+2028 and U+2029 to a space, or dropped a leading U+FEFF. They are now written as the escape that stands for each, in a quoted string, and never plain or in a literal block.
42 lines
2.9 KiB
Swift
42 lines
2.9 KiB
Swift
@testable import PureYAML
|
|
import Testing
|
|
|
|
/// What a string holds is what it comes back as. The meaning of each text here is written down (YAML 1.2.2, section 5.7: an escape in a double-quoted scalar stands for
|
|
/// any character, including a control character), and not taken from what the reader says of it.
|
|
@Suite("String characters")
|
|
struct StringCharactersTests {
|
|
/// Characters that are not printable in a YAML stream and so are not written bare, with the escape that stands for each.
|
|
static let escaped: [(source: String, character: String)] = [
|
|
("\\0", "\u{0}"), ("\\x01", "\u{1}"), ("\\u0001", "\u{1}"), ("\\U00000001", "\u{1}"), ("\\x1f", "\u{1F}"), ("\\u001F", "\u{1F}"),
|
|
("\\x7f", "\u{7F}"), ("\\u007F", "\u{7F}"), ("\\x80", "\u{80}"), ("\\x9f", "\u{9F}"), ("\\N", "\u{85}"), ("\\x85", "\u{85}"),
|
|
("\\L", "\u{2028}"), ("\\u2028", "\u{2028}"), ("\\P", "\u{2029}"), ("\\u2029", "\u{2029}"), ("\\uFEFF", "\u{FEFF}"),
|
|
]
|
|
|
|
@Test("An escape in a double-quoted scalar stands for its character, whatever the character is", arguments: escaped)
|
|
func test_escapeStandsForItsCharacter(_ escape: (source: String, character: String)) throws {
|
|
#expect(try PureYAML.parse("\"\(escape.source)\"") == .string(escape.character))
|
|
#expect(try PureYAML.parse("\"a\(escape.source)b\"") == .string("a\(escape.character)b"))
|
|
#expect(try PureYAML.parse("k: \"\(escape.source)\"") == .mapping(.init([.init(key: "k", value: .string(escape.character))])))
|
|
}
|
|
|
|
/// Strings a writer has to quote or escape, so that the reader gets the same string back.
|
|
static let strings: [String] = [
|
|
"", " ", "x", "a b", "true", "null", "1", "1.5", "- x", "a: b", "# c", "\u{0}", "\u{1}", "\u{1F}", "\u{7F}", "\u{80}", "\u{85}", "\u{9F}", "\u{A0}",
|
|
"\u{2028}", "\u{2029}", "a\u{2028}b", "a\u{85}b", "\u{FEFF}", "\u{FEFF}x", "x\u{FEFF}", "a\u{FEFF}b", "\u{FFFE}", "\u{FFFF}", "tab\there", "line\nbreak",
|
|
"cr\rlf", "\r\n", "\u{200B}", "é", "日本語", "😀",
|
|
]
|
|
|
|
@Test("A string that is dumped is read back as the same string", arguments: strings)
|
|
func test_dumpedStringIsReadBack(_ string: String) throws {
|
|
let value = PureYAML.Model.Value.string(string)
|
|
let dumped = PureYAML.dump(value)
|
|
#expect(try PureYAML.parse(dumped) == value, "\(string.unicodeScalars.map(\.value)) dumped as \(dumped.debugDescription)")
|
|
let inside = PureYAML.Model.Value.mapping(.init([.init(key: "k", value: value)]))
|
|
let dumpedInside = PureYAML.dump(inside)
|
|
#expect(try PureYAML.parse(dumpedInside) == inside, "\(string.unicodeScalars.map(\.value)) dumped as \(dumpedInside.debugDescription)")
|
|
let asKey = PureYAML.Model.Value.mapping(.init([.init(key: string, value: .int(1))]))
|
|
let dumpedKey = PureYAML.dump(asKey)
|
|
#expect(try PureYAML.parse(dumpedKey) == asKey, "\(string.unicodeScalars.map(\.value)) dumped as \(dumpedKey.debugDescription)")
|
|
}
|
|
}
|