Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate FoundationEssentialsTests to Swift Testing #545

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions Benchmarks/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,16 @@ let package = Package(
.plugin(name: "BenchmarkPlugin", package: "package-benchmark")
]
),
.executableTarget(
name: "AttributedStringBenchmarks",
dependencies: [
.product(name: "FoundationEssentials", package: "swift-foundation-local"),
.product(name: "Benchmark", package: "package-benchmark"),
],
path: "Benchmarks/AttributedString",
plugins: [
.plugin(name: "BenchmarkPlugin", package: "package-benchmark")
]
),
]
)
11 changes: 7 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ let package = Package(
exact: "0.0.6"),
.package(
url: "https://github.com/apple/swift-syntax.git",
from: "510.0.0")
from: "510.0.0"),
.package(
url: "https://github.com/apple/swift-testing.git",
branch: "main"),
],
targets: [
// Foundation (umbrella)
Expand Down Expand Up @@ -97,8 +100,8 @@ let package = Package(
.testTarget(
name: "FoundationEssentialsTests",
dependencies: [
"TestSupport",
"FoundationEssentials"
"FoundationEssentials",
.product(name: "Testing", package: "swift-testing"),
],
resources: [
.copy("Resources")
Expand Down Expand Up @@ -141,7 +144,7 @@ let package = Package(
"TestSupport"
],
swiftSettings: availabilityMacros
)
),
]
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,6 @@ func expectDoesNotThrow(_ test: () throws -> Void, _ message: @autoclosure () ->
XCTAssertNoThrow(try test(), message(), file: file, line: line)
}

func expectTrue(_ actual: Bool, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) {
XCTAssertTrue(actual, message(), file: file, line: line)
}

func expectFalse(_ actual: Bool, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) {
XCTAssertFalse(actual, message(), file: file, line: line)
}

public func expectEqual<T: Equatable>(_ expected: T, _ actual: T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) {
XCTAssertEqual(expected, actual, message(), file: file, line: line)
}
Expand Down Expand Up @@ -80,28 +72,6 @@ public func expectEqual(
XCTAssertTrue(expected == actual, message(), file: file, line: line)
}

public func expectEqualSequence< Expected: Sequence, Actual: Sequence>(
_ expected: Expected, _ actual: Actual,
_ message: @autoclosure () -> String = "",
file: String = #file, line: UInt = #line,
sameValue: (Expected.Element, Expected.Element) -> Bool
) where Expected.Element == Actual.Element {
if !expected.elementsEqual(actual, by: sameValue) {
XCTFail("expected elements: \"\(expected)\"\n"
+ "actual: \"\(actual)\" (of type \(String(reflecting: type(of: actual)))), \(message())")
}
}

public func expectEqualSequence< Expected: Sequence, Actual: Sequence>(
_ expected: Expected, _ actual: Actual,
_ message: @autoclosure () -> String = "",
file: String = #file, line: UInt = #line
) where Expected.Element == Actual.Element, Expected.Element: Equatable {
expectEqualSequence(expected, actual, message()) {
$0 == $1
}
}

func expectEqual(_ actual: Date, _ expected: Date , within: Double = 0.001, file: StaticString = #file, line: UInt = #line) {
let debugDescription = "\nactual: \(actual.formatted(.iso8601));\nexpected: \(expected.formatted(.iso8601))"
XCTAssertEqual(actual.timeIntervalSinceReferenceDate, expected.timeIntervalSinceReferenceDate, accuracy: within, debugDescription, file: file, line: line)
Expand Down Expand Up @@ -170,7 +140,7 @@ func expectNoChanges<T: BinaryInteger>(_ check: @autoclosure () -> T, by differe
///
/// - Note: `oracle` is also checked for conformance to the
/// laws.
public func checkEquatable<Instances: Collection>(
public func checkEquatableXCTest<Instances: Collection>(
_ instances: Instances,
oracle: (Instances.Index, Instances.Index) -> Bool,
allowBrokenTransitivity: Bool = false,
Expand All @@ -196,7 +166,7 @@ private class Box<T> {
}
}

internal func _checkEquatableImpl<Instance : Equatable>(
fileprivate func _checkEquatableImpl<Instance : Equatable>(
_ instances: [Instance],
oracle: (Int, Int) -> Bool,
allowBrokenTransitivity: Bool = false,
Expand All @@ -211,7 +181,7 @@ internal func _checkEquatableImpl<Instance : Equatable>(

for i in instances.indices {
let x = instances[i]
expectTrue(oracle(i, i), "bad oracle: broken reflexivity at index \(i)")
XCTAssertTrue(oracle(i, i), "bad oracle: broken reflexivity at index \(i)")

for j in instances.indices {
let y = instances[j]
Expand Down Expand Up @@ -255,7 +225,7 @@ internal func _checkEquatableImpl<Instance : Equatable>(
transitivityScoreboard[i].value.insert(i)
}
for k in transitivityScoreboard[i].value {
expectTrue(
XCTAssertTrue(
oracle(j, k),
"bad oracle: broken transitivity at indices \(i), \(j), \(k)",
file: file,
Expand All @@ -280,14 +250,14 @@ func hash<H: Hashable>(_ value: H, salt: Int? = nil) -> Int {
return hasher.finalize()
}

public func checkHashable<Instances: Collection>(
public func checkHashableXCTest<Instances: Collection>(
_ instances: Instances,
equalityOracle: (Instances.Index, Instances.Index) -> Bool,
allowIncompleteHashing: Bool = false,
_ message: @autoclosure () -> String = "",
file: StaticString = #file, line: UInt = #line
) where Instances.Element: Hashable {
checkHashable(
checkHashableXCTest(
instances,
equalityOracle: equalityOracle,
hashEqualityOracle: equalityOracle,
Expand All @@ -298,7 +268,7 @@ public func checkHashable<Instances: Collection>(
}


public func checkHashable<Instances: Collection>(
public func checkHashableXCTest<Instances: Collection>(
_ instances: Instances,
equalityOracle: (Instances.Index, Instances.Index) -> Bool,
hashEqualityOracle: (Instances.Index, Instances.Index) -> Bool,
Expand All @@ -307,7 +277,7 @@ public func checkHashable<Instances: Collection>(
file: StaticString = #file, line: UInt = #line
) where Instances.Element: Hashable {

checkEquatable(
checkEquatableXCTest(
instances,
oracle: equalityOracle,
message(),
Expand Down Expand Up @@ -405,7 +375,7 @@ public func checkHashableGroups<Groups: Collection>(
func equalityOracle(_ lhs: Int, _ rhs: Int) -> Bool {
return groupIndices[lhs] == groupIndices[rhs]
}
checkHashable(
checkHashableXCTest(
instances,
equalityOracle: equalityOracle,
hashEqualityOracle: equalityOracle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
//
//===----------------------------------------------------------------------===//

#if canImport(TestSupport)
import TestSupport
#endif
import Testing

#if FOUNDATION_FRAMEWORK
@testable import Foundation
Expand All @@ -27,8 +25,8 @@ extension AttributedStringProtocol {
}

/// Tests for `AttributedString` to confirm expected CoW behavior
final class TestAttributedStringCOW: XCTestCase {
final class AttributedStringCOWTests {

// MARK: - Utility Functions

func createAttributedString() -> AttributedString {
Expand All @@ -42,15 +40,29 @@ final class TestAttributedStringCOW: XCTestCase {
let str = createAttributedString()
var copy = str
operation(&copy)
XCTAssertNotEqual(str, copy, "Mutation operation did not copy when multiple references exist", file: file, line: line)
#expect(
str != copy,
"Mutation operation did not copy when multiple references exist",
sourceLocation: .init(
filePath: String(describing: file),
line: Int(line)
)
)
}

func assertCOWNoCopy(file: StaticString = #file, line: UInt = #line, _ operation: (inout AttributedString) -> Void) {
var str = createAttributedString()
let gutsPtr = Unmanaged.passUnretained(str._guts)
operation(&str)
let newGutsPtr = Unmanaged.passUnretained(str._guts)
XCTAssertEqual(gutsPtr.toOpaque(), newGutsPtr.toOpaque(), "Mutation operation copied when only one reference exists", file: file, line: line)
#expect(
gutsPtr.toOpaque() == newGutsPtr.toOpaque(),
"Mutation operation copied when only one reference exists",
sourceLocation: .init(
filePath: String(describing: file),
line: Int(line)
)
)
}

func assertCOWBehavior(file: StaticString = #file, line: UInt = #line, _ operation: (inout AttributedString) -> Void) {
Expand All @@ -76,7 +88,7 @@ final class TestAttributedStringCOW: XCTestCase {

// MARK: - Tests

func testTopLevelType() {
@Test func testTopLevelType() {
assertCOWBehavior { (str) in
str.setAttributes(container)
}
Expand Down Expand Up @@ -109,7 +121,7 @@ final class TestAttributedStringCOW: XCTestCase {
}
}

func testSubstring() {
@Test func testSubstring() {
assertCOWBehavior { (str) in
str[makeSubrange(str)].setAttributes(container)
}
Expand All @@ -130,7 +142,7 @@ final class TestAttributedStringCOW: XCTestCase {
}
}

func testCharacters() {
@Test func testCharacters() {
let char: Character = "a"

assertCOWBehavior { (str) in
Expand All @@ -153,15 +165,15 @@ final class TestAttributedStringCOW: XCTestCase {
}
}

func testUnicodeScalars() {
@Test func testUnicodeScalars() {
let scalar: UnicodeScalar = "a"

assertCOWBehavior { (str) in
str.unicodeScalars.replaceSubrange(makeSubrange(str), with: [scalar, scalar])
}
}

func testGenericProtocol() {
@Test func testGenericProtocol() {
assertCOWBehavior {
$0.genericSetAttribute()
}
Expand Down