From fe38fdec9c061ce2ba2d7d92d27f72d45680446e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 17 Aug 2020 10:15:38 -0700 Subject: [PATCH 1/2] Fix #filePath mis-threading. --- Tests/PenguinCSVTests/CSVInterpreterTests.swift | 14 +++++++------- Tests/PenguinCSVTests/CSVReaderTests.swift | 2 +- .../NonBlockingThreadPoolTests.swift | 2 +- Tests/PenguinTablesTests/CSVParsibleTests.swift | 2 +- Tests/PenguinTablesTests/StringParsibleTests.swift | 4 ++-- Tests/PenguinTablesTests/TableTests.swift | 3 ++- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Tests/PenguinCSVTests/CSVInterpreterTests.swift b/Tests/PenguinCSVTests/CSVInterpreterTests.swift index 27df837c..e40e648d 100644 --- a/Tests/PenguinCSVTests/CSVInterpreterTests.swift +++ b/Tests/PenguinCSVTests/CSVInterpreterTests.swift @@ -291,7 +291,7 @@ final class CSVInterpreterTests: XCTestCase { } fileprivate func assertCompatible( - _ cell: String, with type: CSVType, file: StaticString = #file, line: UInt = #line + _ cell: String, with type: CSVType, file: StaticString = #filePath, line: UInt = #line ) { XCTAssert( type.isCompatibleWith(cell), "\(type) should be compatible with \(cell)", file: file, line: line @@ -299,7 +299,7 @@ fileprivate func assertCompatible( } fileprivate func assertNotCompatible( - _ cell: String, with type: CSVType, file: StaticString = #file, line: UInt = #line + _ cell: String, with type: CSVType, file: StaticString = #filePath, line: UInt = #line ) { XCTAssertFalse( type.isCompatibleWith(cell), "\(type) should not be compatible with \(cell)", file: file, @@ -338,7 +338,7 @@ fileprivate func assertEqual( } fileprivate func checkColumnGuesser( - expected: [CSVType], best: CSVType, cells: String..., file: StaticString = #file, + expected: [CSVType], best: CSVType, cells: String..., file: StaticString = #filePath, line: UInt = #line ) { var guesser = CSVColumnGuesser() @@ -354,7 +354,7 @@ fileprivate func checkColumnSniffing( withFirstRow: [CSVType], _ contents: String, separator: Unicode.Scalar = ",", - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line ) { precondition( @@ -377,7 +377,7 @@ fileprivate func checkColumnSniffing( fileprivate func checkComputeColumnNames( expected: [String], separator: Unicode.Scalar = ",", _ contents: String, - file: StaticString = #file, line: UInt = #line + file: StaticString = #filePath, line: UInt = #line ) { var c = contents c.withUTF8 { contents in @@ -389,14 +389,14 @@ fileprivate func checkComputeColumnNames( } fileprivate func assertColumnNames( - _ expected: [String], _ result: CSVGuess, file: StaticString = #file, line: UInt = #line + _ expected: [String], _ result: CSVGuess, file: StaticString = #filePath, line: UInt = #line ) { let actual = result.columns.map { $0.name } XCTAssertEqual(expected, actual, file: file, line: line) } fileprivate func assertColumnTypes( - _ expected: [CSVType], _ result: CSVGuess, file: StaticString = #file, line: UInt = #line + _ expected: [CSVType], _ result: CSVGuess, file: StaticString = #filePath, line: UInt = #line ) { let actual = result.columns.map { $0.type } XCTAssertEqual(expected, actual, file: file, line: line) diff --git a/Tests/PenguinCSVTests/CSVReaderTests.swift b/Tests/PenguinCSVTests/CSVReaderTests.swift index d6ad89b5..f9cd23df 100644 --- a/Tests/PenguinCSVTests/CSVReaderTests.swift +++ b/Tests/PenguinCSVTests/CSVReaderTests.swift @@ -259,7 +259,7 @@ fileprivate enum TestError: Error { } fileprivate func assertMetadataNotNil( - _ reader: CSVReader, file: StaticString = #file, line: UInt = #line + _ reader: CSVReader, file: StaticString = #filePath, line: UInt = #line ) throws -> CSVGuess { XCTAssertNotNil(reader.metadata, file: file, line: line) guard let metadata = reader.metadata else { throw TestError.missingMetadata } diff --git a/Tests/PenguinParallelTests/NonBlockingThreadPoolTests.swift b/Tests/PenguinParallelTests/NonBlockingThreadPoolTests.swift index 450d6951..1268460b 100644 --- a/Tests/PenguinParallelTests/NonBlockingThreadPoolTests.swift +++ b/Tests/PenguinParallelTests/NonBlockingThreadPoolTests.swift @@ -111,7 +111,7 @@ final class NonBlockingThreadPoolTests: XCTestCase { // Overload for 2-tuple fileprivate func XCTAssertEqual( - _ lhs: (Int, Int), _ rhs: (Int, Int), _ msg: String = "", file: StaticString = #file, + _ lhs: (Int, Int), _ rhs: (Int, Int), _ msg: String = "", file: StaticString = #filePath, line: UInt = #line ) { XCTAssertEqual( diff --git a/Tests/PenguinTablesTests/CSVParsibleTests.swift b/Tests/PenguinTablesTests/CSVParsibleTests.swift index 25b377c9..477ed77e 100644 --- a/Tests/PenguinTablesTests/CSVParsibleTests.swift +++ b/Tests/PenguinTablesTests/CSVParsibleTests.swift @@ -33,7 +33,7 @@ final class CSVParsibleTests: XCTestCase { fileprivate func assertParse( _ bytes: String, as val: T, - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line ) { var s = bytes diff --git a/Tests/PenguinTablesTests/StringParsibleTests.swift b/Tests/PenguinTablesTests/StringParsibleTests.swift index 9655fcdb..9730db7b 100644 --- a/Tests/PenguinTablesTests/StringParsibleTests.swift +++ b/Tests/PenguinTablesTests/StringParsibleTests.swift @@ -68,7 +68,7 @@ final class StringParsibleTests: XCTestCase { } fileprivate func assertParses( - expected: T, source: String, file: StaticString = #file, line: UInt = #line + expected: T, source: String, file: StaticString = #filePath, line: UInt = #line ) { let result = T(parsing: source) XCTAssertEqual(expected, result, file: file, line: line) @@ -78,7 +78,7 @@ fileprivate func assertParseFailure( a type: T.Type, from source: String, reason: String? = nil, - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line ) { do { diff --git a/Tests/PenguinTablesTests/TableTests.swift b/Tests/PenguinTablesTests/TableTests.swift index 0573ce9d..f4d8ad27 100644 --- a/Tests/PenguinTablesTests/TableTests.swift +++ b/Tests/PenguinTablesTests/TableTests.swift @@ -278,7 +278,8 @@ final class TableTests: XCTestCase { } fileprivate func assertPColumnsEqual( - _ lhs: PColumn?, _ rhs: PColumn?, dtype: T.Type, file: StaticString = #file, line: UInt = #line + _ lhs: PColumn?, _ rhs: PColumn?, dtype: T.Type, + file: StaticString = #filePath, line: UInt = #line ) { if lhs == nil && rhs == nil { return } From c539543fec2688e1ea769808e8973b221801485d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 22 Oct 2020 09:26:17 -0700 Subject: [PATCH 2/2] Make #filePath threading backward-compatible. --- .../PenguinCSVTests/CSVInterpreterTests.swift | 99 +++++++++++++++++++ Tests/PenguinCSVTests/CSVReaderTests.swift | 10 ++ .../NonBlockingThreadPoolTests.swift | 12 +++ .../PenguinTablesTests/CSVParsibleTests.swift | 15 +++ .../StringParsibleTests.swift | 32 ++++++ Tests/PenguinTablesTests/TableTests.swift | 23 +++++ 6 files changed, 191 insertions(+) diff --git a/Tests/PenguinCSVTests/CSVInterpreterTests.swift b/Tests/PenguinCSVTests/CSVInterpreterTests.swift index e40e648d..7aaeffd5 100644 --- a/Tests/PenguinCSVTests/CSVInterpreterTests.swift +++ b/Tests/PenguinCSVTests/CSVInterpreterTests.swift @@ -290,6 +290,7 @@ final class CSVInterpreterTests: XCTestCase { ] } +#if swift(>=5.3) fileprivate func assertCompatible( _ cell: String, with type: CSVType, file: StaticString = #filePath, line: UInt = #line ) { @@ -319,6 +320,37 @@ fileprivate func assertParsedHeuristics( assertEqual(heuristics, separatorHeuristics, file: file, line: line) } } +#else +fileprivate func assertCompatible( + _ cell: String, with type: CSVType, file: StaticString = #file, line: UInt = #line +) { + XCTAssert( + type.isCompatibleWith(cell), "\(type) should be compatible with \(cell)", file: file, line: line + ) +} + +fileprivate func assertNotCompatible( + _ cell: String, with type: CSVType, file: StaticString = #file, line: UInt = #line +) { + XCTAssertFalse( + type.isCompatibleWith(cell), "\(type) should not be compatible with \(cell)", file: file, + line: line) +} + +fileprivate func assertParsedHeuristics( + _ text: String, _ heuristics: [SeparatorHeuristics], file: StaticString = #file, + line: UInt = #line +) { + var text2 = text // Make a mutable copy, as withUTF8 might modify the string. + text2.withUTF8 { body in + let lines = body.split(separator: UInt8(ascii: "\n")) + precondition(lines.count > 2) + let fullLines = lines[0..=5.3) fileprivate func checkColumnGuesser( expected: [CSVType], best: CSVType, cells: String..., file: StaticString = #filePath, line: UInt = #line @@ -401,6 +434,72 @@ fileprivate func assertColumnTypes( let actual = result.columns.map { $0.type } XCTAssertEqual(expected, actual, file: file, line: line) } +#else +fileprivate func checkColumnGuesser( + expected: [CSVType], best: CSVType, cells: String..., file: StaticString = #file, + line: UInt = #line +) { + var guesser = CSVColumnGuesser() + for cell in cells { + guesser.updateCompatibilities(cell: cell) + } + XCTAssertEqual(Set(expected), guesser.possibleTypes, "Cells: \(cells)", file: file, line: line) + XCTAssertEqual(best, guesser.bestGuess, "Cells: \(cells)", file: file, line: line) +} + +fileprivate func checkColumnSniffing( + withoutFirstRow: [CSVType], + withFirstRow: [CSVType], + _ contents: String, + separator: Unicode.Scalar = ",", + file: StaticString = #file, + line: UInt = #line +) { + precondition( + withoutFirstRow.count == withFirstRow.count, + "Mismatched counts: \(withoutFirstRow.count) and \(withFirstRow.count)") + var c = contents // Must make a mutable copy first. :-( + c.withUTF8 { contents in + let lines = contents.split(separator: UInt8(ascii: "\n")) + let allLines = lines[0..=5.3) fileprivate func assertMetadataNotNil( _ reader: CSVReader, file: StaticString = #filePath, line: UInt = #line ) throws -> CSVGuess { @@ -265,3 +266,12 @@ fileprivate func assertMetadataNotNil( guard let metadata = reader.metadata else { throw TestError.missingMetadata } return metadata } +#else +fileprivate func assertMetadataNotNil( + _ reader: CSVReader, file: StaticString = #file, line: UInt = #line +) throws -> CSVGuess { + XCTAssertNotNil(reader.metadata, file: file, line: line) + guard let metadata = reader.metadata else { throw TestError.missingMetadata } + return metadata +} +#endif diff --git a/Tests/PenguinParallelTests/NonBlockingThreadPoolTests.swift b/Tests/PenguinParallelTests/NonBlockingThreadPoolTests.swift index 1268460b..81ca845e 100644 --- a/Tests/PenguinParallelTests/NonBlockingThreadPoolTests.swift +++ b/Tests/PenguinParallelTests/NonBlockingThreadPoolTests.swift @@ -110,6 +110,7 @@ final class NonBlockingThreadPoolTests: XCTestCase { } // Overload for 2-tuple +#if swift(>=5.3) fileprivate func XCTAssertEqual( _ lhs: (Int, Int), _ rhs: (Int, Int), _ msg: String = "", file: StaticString = #filePath, line: UInt = #line @@ -119,6 +120,17 @@ fileprivate func XCTAssertEqual( XCTAssertEqual( lhs.1, rhs.1, "items 1 did not agree: \(lhs) vs \(rhs) \(msg)", file: file, line: line) } +#else +fileprivate func XCTAssertEqual( + _ lhs: (Int, Int), _ rhs: (Int, Int), _ msg: String = "", file: StaticString = #file, + line: UInt = #line +) { + XCTAssertEqual( + lhs.0, rhs.0, "items 0 did not agree: \(lhs) vs \(rhs) \(msg)", file: file, line: line) + XCTAssertEqual( + lhs.1, rhs.1, "items 1 did not agree: \(lhs) vs \(rhs) \(msg)", file: file, line: line) +} +#endif /// A platform to count threads and to ensure deallocation. /// diff --git a/Tests/PenguinTablesTests/CSVParsibleTests.swift b/Tests/PenguinTablesTests/CSVParsibleTests.swift index 477ed77e..36bed794 100644 --- a/Tests/PenguinTablesTests/CSVParsibleTests.swift +++ b/Tests/PenguinTablesTests/CSVParsibleTests.swift @@ -30,6 +30,7 @@ final class CSVParsibleTests: XCTestCase { ] } +#if swift(>=5.3) fileprivate func assertParse( _ bytes: String, as val: T, @@ -42,3 +43,17 @@ fileprivate func assertParse( XCTAssertEqual(parsed, val, file: file, line: line) } } +#else +fileprivate func assertParse( + _ bytes: String, + as val: T, + file: StaticString = #file, + line: UInt = #line +) { + var s = bytes + s.withUTF8 { s in + let parsed = T(CSVCell.raw(s)) + XCTAssertEqual(parsed, val, file: file, line: line) + } +} +#endif diff --git a/Tests/PenguinTablesTests/StringParsibleTests.swift b/Tests/PenguinTablesTests/StringParsibleTests.swift index 9730db7b..b0d020f1 100644 --- a/Tests/PenguinTablesTests/StringParsibleTests.swift +++ b/Tests/PenguinTablesTests/StringParsibleTests.swift @@ -67,6 +67,7 @@ final class StringParsibleTests: XCTestCase { ] } +#if swift(>=5.3) fileprivate func assertParses( expected: T, source: String, file: StaticString = #filePath, line: UInt = #line ) { @@ -96,3 +97,34 @@ fileprivate func assertParseFailure( } } } +#else +fileprivate func assertParses( + expected: T, source: String, file: StaticString = #file, line: UInt = #line +) { + let result = T(parsing: source) + XCTAssertEqual(expected, result, file: file, line: line) +} + +fileprivate func assertParseFailure( + a type: T.Type, + from source: String, + reason: String? = nil, + file: StaticString = #file, + line: UInt = #line +) { + do { + let unexpected = try T(parseOrThrow: source) + XCTFail( + "\"\(source)\" parsed as \(type) unexpectedly as \(unexpected).", file: file, line: line) + } catch { + let msg = String(describing: error) + if let reason = reason { + XCTAssert( + msg.contains(reason), + "Error message \"\(msg)\" did not contain expected string \"\(reason)\".", + file: file, + line: line) + } + } +} +#endif diff --git a/Tests/PenguinTablesTests/TableTests.swift b/Tests/PenguinTablesTests/TableTests.swift index f4d8ad27..13177b95 100644 --- a/Tests/PenguinTablesTests/TableTests.swift +++ b/Tests/PenguinTablesTests/TableTests.swift @@ -277,6 +277,7 @@ final class TableTests: XCTestCase { ] } +#if swift(>=5.3) fileprivate func assertPColumnsEqual( _ lhs: PColumn?, _ rhs: PColumn?, dtype: T.Type, file: StaticString = #filePath, line: UInt = #line @@ -297,3 +298,25 @@ fileprivate func assertPColumnsEqual( } XCTAssertEqual(lhsT, rhsT, file: file, line: line) } +#else +fileprivate func assertPColumnsEqual( + _ lhs: PColumn?, _ rhs: PColumn?, dtype: T.Type, + file: StaticString = #file, line: UInt = #line +) { + if lhs == nil && rhs == nil { return } + + guard let lhsT: PTypedColumn = try? lhs?.asDType() else { + XCTFail( + "lhs could not be interpreted as dtype \(dtype): \(String(describing: lhs))", + file: file, line: line) + return + } + guard let rhsT: PTypedColumn = try? rhs?.asDType() else { + XCTFail( + "rhs could not be interpreted as dtype \(dtype): \(String(describing: rhs))", + file: file, line: line) + return + } + XCTAssertEqual(lhsT, rhsT, file: file, line: line) +} +#endif