diff --git a/Package.swift b/Package.swift index 3b9d616c3..b9b9d6d71 100644 --- a/Package.swift +++ b/Package.swift @@ -58,9 +58,10 @@ let package = Package( .executable( name: "VariadicsGenerator", targets: ["VariadicsGenerator"]), - .executable( - name: "RegexBenchmark", - targets: ["RegexBenchmark"]) +// Disable to work around rdar://126877024 +// .executable( +// name: "RegexBenchmark", +// targets: ["RegexBenchmark"]) ], dependencies: [ .package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"), @@ -142,17 +143,17 @@ let package = Package( "_StringProcessing" ], swiftSettings: [availabilityDefinition]), - .executableTarget( - name: "RegexBenchmark", - dependencies: [ - .product(name: "ArgumentParser", package: "swift-argument-parser"), - "_RegexParser", - "_StringProcessing", - "RegexBuilder" - ], - swiftSettings: [ - .unsafeFlags(["-Xfrontend", "-disable-availability-checking"]), - ]), +// .executableTarget( +// name: "RegexBenchmark", +// dependencies: [ +// .product(name: "ArgumentParser", package: "swift-argument-parser"), +// "_RegexParser", +// "_StringProcessing", +// "RegexBuilder" +// ], +// swiftSettings: [ +// .unsafeFlags(["-Xfrontend", "-disable-availability-checking"]), +// ]), // MARK: Exercises .target( diff --git a/Tests/RegexBuilderTests/AnyRegexOutputTests.swift b/Tests/RegexBuilderTests/AnyRegexOutputTests.swift index 165d1d411..6e36f4d9d 100644 --- a/Tests/RegexBuilderTests/AnyRegexOutputTests.swift +++ b/Tests/RegexBuilderTests/AnyRegexOutputTests.swift @@ -5,153 +5,137 @@ import RegexBuilder private let enablePrinting = false -@available(SwiftStdlib 5.7, *) -extension RegexDSLTests { - - func testContrivedAROExample() { - // Find and extract potential IDs. IDs are 8 bytes encoded as - // 16 hexadecimal numbers, with an optional `-` between every - // double-byte (i.e. 4 hex digits). - // - // AAAA-BBBB-CCCC-DDDD - // AAAABBBBCCCCDDDD - // AAAABBBBCCCC-DDDD - // - // IDs are converted to uppercase and hyphen separated - // - // The regex can have special capture names which affect replacement - // behavior - // - "salient": presented uppercase in square brackets after - // - "note": presented lowercase in parens - // - none: nothing - // - no captures: "" - // - let input = """ - Machine 1234-5678-90ab-CDEF connected - Session FEDCAB0987654321 ended - Artiface 0011deff-2231-abcd contrived - """ - let noCapOutput = """ - Machine connected - Session ended - Artiface contrived - """ - let unnamedOutput = """ - Machine 1234-5678-90AB-CDEF connected - Session FEDC-AB09-8765-4321 ended - Artiface 0011-DEFF-2231-ABCD contrived - """ - let salientOutput = """ - Machine 1234-5678-90AB-CDEF [5678] connected - Session FEDC-AB09-8765-4321 [AB09] ended - Artiface 0011-DEFF-2231-ABCD [DEFF] contrived - """ - let noteOutput = """ - Machine 1234-5678-90AB-CDEF (5678) connected - Session FEDC-AB09-8765-4321 (ab09) ended - Artiface 0011-DEFF-2231-ABCD (deff) contrived - """ - - enum Kind { - case none - case unnamed - case salient - case note - - func contains(captureNamed s: String) -> Bool { - switch self { - case .none: return false - case .unnamed: return false - case .salient: return s == "salient" - case .note: return s == "note" - } - } - - var expected: String { - switch self { - case .none: return """ - Machine connected - Session ended - Artiface contrived - """ - case .unnamed: return """ - Machine 1234-5678-90AB-CDEF connected - Session FEDC-AB09-8765-4321 ended - Artiface 0011-DEFF-2231-ABCD contrived - """ - case .salient: return """ - Machine 1234-5678-90AB-CDEF [5678] connected - Session FEDC-AB09-8765-4321 [AB09] ended - Artiface 0011-DEFF-2231-ABCD [DEFF] contrived - """ - case .note: return """ - Machine 1234-5678-90AB-CDEF (5678) connected - Session FEDC-AB09-8765-4321 (ab09) ended - Artiface 0011-DEFF-2231-ABCD (deff) contrived - """ - } - } +// Find and extract potential IDs. IDs are 8 bytes encoded as +// 16 hexadecimal numbers, with an optional `-` between every +// double-byte (i.e. 4 hex digits). +// +// AAAA-BBBB-CCCC-DDDD +// AAAABBBBCCCCDDDD +// AAAABBBBCCCC-DDDD +// +// IDs are converted to uppercase and hyphen separated +// +// The regex can have special capture names which affect replacement +// behavior +// - "salient": presented uppercase in square brackets after +// - "note": presented lowercase in parens +// - none: nothing +// - no captures: "" +fileprivate let input = """ + Machine 1234-5678-90ab-CDEF connected + Session FEDCAB0987654321 ended + Artiface 0011deff-2231-abcd contrived + """ +fileprivate let noCapOutput = """ + Machine connected + Session ended + Artiface contrived + """ +fileprivate let unnamedOutput = """ + Machine 1234-5678-90AB-CDEF connected + Session FEDC-AB09-8765-4321 ended + Artiface 0011-DEFF-2231-ABCD contrived + """ +fileprivate let salientOutput = """ + Machine 1234-5678-90AB-CDEF [5678] connected + Session FEDC-AB09-8765-4321 [AB09] ended + Artiface 0011-DEFF-2231-ABCD [DEFF] contrived + """ +fileprivate let noteOutput = """ + Machine 1234-5678-90AB-CDEF (5678) connected + Session FEDC-AB09-8765-4321 (ab09) ended + Artiface 0011-DEFF-2231-ABCD (deff) contrived + """ + +fileprivate enum Kind { + case none + case unnamed + case salient + case note + + func contains(captureNamed s: String) -> Bool { + switch self { + case .none: return false + case .unnamed: return false + case .salient: return s == "salient" + case .note: return s == "note" } + } - func checkContains( - _ re: Regex, _ kind: Kind - ) { - for name in ["", "salient", "note", "other"] { - XCTAssertEqual( - kind.contains(captureNamed: name), re.contains(captureNamed: name)) - } + var expected: String { + switch self { + case .none: return noCapOutput + case .unnamed: return unnamedOutput + case .salient: return salientOutput + case .note: return noteOutput } - func checkAROReplacing( - _ re: Regex, _ kind: Kind - ) { - let aro = Regex(re) - let output = input.replacing(aro) { - (match: Regex.Match) -> String in - - if match.count < 5 { return "" } + } +} - let suffix: String - if re.contains(captureNamed: "salient") { - let body = match["salient"]!.substring?.uppercased() ?? "" - suffix = " [\(body)]" - } else if re.contains(captureNamed: "note") { - let body = match["note"]!.substring?.lowercased() ?? "" - suffix = " (\(body))" - } else { - suffix = "" - } +fileprivate func checkContains( + _ re: Regex, _ kind: Kind +) { + for name in ["", "salient", "note", "other"] { + XCTAssertEqual( + kind.contains(captureNamed: name), re.contains(captureNamed: name)) + } +} - return match.output.dropFirst().lazy.map { - $0.substring!.uppercased() - }.joined(separator: "-") + suffix - } +fileprivate func checkAROReplacing( + _ re: Regex, _ kind: Kind +) { + let aro = Regex(re) + let output = input.replacing(aro) { + (match: Regex.Match) -> String in + + if match.count < 5 { return "" } + + let suffix: String + if re.contains(captureNamed: "salient") { + let body = match["salient"]!.substring?.uppercased() ?? "" + suffix = " [\(body)]" + } else if re.contains(captureNamed: "note") { + let body = match["note"]!.substring?.lowercased() ?? "" + suffix = " (\(body))" + } else { + suffix = "" + } - XCTAssertEqual(output, kind.expected) + return match.output.dropFirst().lazy.map { + $0.substring!.uppercased() + }.joined(separator: "-") + suffix + } - if enablePrinting { - print("---") - print(output) - print(kind) - } - } - func check( - _ re: Regex, _ kind: Kind, _ expected: String - ) { - let aro = Regex(re) + XCTAssertEqual(output, kind.expected) - let casted = try! XCTUnwrap(Regex(aro, as: Output.self)) + if enablePrinting { + print("---") + print(output) + print(kind) + } +} - // contains(captureNamed:) - checkContains(re, kind) - checkContains(aro, kind) - checkContains(casted, kind) +fileprivate func check( + _ re: Regex, _ kind: Kind, _ expected: String +) { + let aro = Regex(re) + let casted = try! XCTUnwrap(Regex(aro, as: Output.self)) + + // contains(captureNamed:) + checkContains(re, kind) + checkContains(aro, kind) + checkContains(casted, kind) + + // replacing + checkAROReplacing(re, kind) + checkAROReplacing(aro, kind) + checkAROReplacing(casted, kind) +} - // replacing - checkAROReplacing(re, kind) - checkAROReplacing(aro, kind) - checkAROReplacing(casted, kind) - } +@available(SwiftStdlib 5.7, *) +extension RegexDSLTests { + func testContrivedAROExample() { // Literals (mocked up via explicit `as` types) check(try! Regex(#""" (?x) @@ -161,6 +145,7 @@ extension RegexDSLTests { .none, noCapOutput ) + check(try! Regex(#""" (?x) (\p{hexdigit}{4}) -? (\p{hexdigit}{4}) -?