Files

98 lines
4.2 KiB
Swift

//===----------------------------------------------------------*- swift -*-===//
//
// This source file is part of the Swift Argument Parser open source project
//
// Copyright (c) 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//
import XCTest
@testable import ArgumentParser
final class StringTokenizedTests: XCTestCase {}
func _testTokens(_ input: [String], _ expected: [String], file: StaticString = #file, line: UInt = #line) {
var input: Array = input.reversed()
let result = readTokens {
input.popLast()
}
XCTAssertEqual(result, expected, file: file, line: line)
}
func _testTokens(_ input: String, _ expected: [String], file: StaticString = #file, line: UInt = #line) {
_testTokens([input], expected, file: file, line: line)
}
extension StringTokenizedTests {
func testTokensSimple() throws {
_testTokens(#""#, [])
_testTokens(#" "#, [])
_testTokens(#"one"#, ["one"])
_testTokens(#" one "#, ["one"])
_testTokens(#"one two three"#, ["one", "two", "three"])
_testTokens(#" one two three"#, ["one", "two", "three"])
_testTokens(#"one two three "#, ["one", "two", "three"])
_testTokens(#"one\ two three"#, ["one two", "three"])
_testTokens(#"one two \ three"#, ["one", "two", " ", "three"])
_testTokens(#"one \ \ two three\ \ "#, ["one", " two", "three "])
}
func testTokensSingleQuotes() throws {
_testTokens(#"one two 'three four'"#, ["one", "two", "three four"])
_testTokens(#"one two 'three four'"#, ["one", "two", "three four"])
_testTokens(#"one two \'three four"#, ["one", "two", #"'three"#, "four"])
_testTokens(#"one two '\'three four'"#, ["one", "two", #"'three four"#])
_testTokens(#"one two '\"three four'"#, ["one", "two", #"\"three four"#])
_testTokens(#"one two 'three " four'"#, ["one", "two", #"three " four"#])
_testTokens(#"one two three' " 'four"#, ["one", "two", #"three " four"#])
_testTokens(#"one two thr'ee " fo'ur"#, ["one", "two", #"three " four"#])
}
func testTokensDoubleQuotes() throws {
_testTokens(#"one two "three four""#, ["one", "two", "three four"])
_testTokens(#"one two "three four""#, ["one", "two", "three four"])
_testTokens(#"one two \"three four"#, ["one", "two", #""three"#, "four"])
_testTokens(#"one two "\"three four""#, ["one", "two", #""three four"#])
_testTokens(#"one two "\'three four""#, ["one", "two", #"\'three four"#])
_testTokens(#"one two "three ' four""#, ["one", "two", #"three ' four"#])
_testTokens(#"one two three" ' "four"#, ["one", "two", #"three ' four"#])
_testTokens(#"one two thr"ee ' fo"ur"#, ["one", "two", #"three ' four"#])
}
func testTokensEscapes() throws {
_testTokens(#"one \a three"#, ["one", #"\a"#, "three"])
}
func testMultipleLines() throws {
// Stop at line break
_testTokens([#"one two three"#, #"four"#], ["one", "two", "three"])
// Quoted sections include line breaks
_testTokens([#"one two 'three"#, #"four'"#], ["one", "two", "three\nfour"])
_testTokens([#"'one"#, #"two"#, #"three"#, #"four'"#], ["one\ntwo\nthree\nfour"])
_testTokens([#"'"#, #"one"#, #"two"#, #"three"#, #"four'"#], ["\none\ntwo\nthree\nfour"])
_testTokens([#"'one"#, #"two"#, #"three"#, #"four"#, #"'"#], ["one\ntwo\nthree\nfour\n"])
// Escaped line breaks continue, but aren't included
_testTokens([#"one two three\"#, #"four'"#], ["one", "two", "threefour"])
_testTokens([#"one\"#, #"two\"#, #"three\"#, #"four'"#], ["onetwothreefour"])
_testTokens(
[#"\"#, #"one\"#, #"two\"#, #"three\"#, #"four"#, #"\"#, #"\"#],
["onetwothreefour"])
// Skip escaped line breaks even in a quoted section
_testTokens([#"one two 'three\"#, #"four'"#], ["one", "two", "threefour"])
}
func testTokenizedEdgeCases() throws {
// Unterminated quotes
_testTokens(#"one two "three"#, ["one", "two", "three"])
_testTokens(#"one two 'three"#, ["one", "two", "three"])
// Backslash in last position
_testTokens(#"one two three\"#, ["one", "two", "three"])
}
}