Files
swift-mirror/validation-test/stdlib/SetAnyHashableExtensions.swift
Erik Eckstein 172f3caf85 tests: make tests more resilient to optimizations by passing values to _blackHole
Without `_blackHole`, the optimizer may remove or make assumptions about values, which are not intended by the test.
This fixes the tests when running them in optimize mode and when OSSA modules are enabled.

This is part of rdar://140229560.
2025-01-27 10:38:30 +01:00

279 lines
8.4 KiB
Swift

// RUN: %target-run-simple-swift
// REQUIRES: executable_test
// Freestanding/minimal runtime does not support printing type names at runtime.
// UNSUPPORTED: freestanding
import StdlibUnittest
class TestHashableBase : Hashable {
var value: Int
var identity: Int
init(_ value: Int, identity: Int) {
self.value = value
self.identity = identity
}
func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
static func == (
lhs: TestHashableBase,
rhs: TestHashableBase
) -> Bool {
return lhs.value == rhs.value
}
}
class TestHashableDerivedA : TestHashableBase {}
class TestHashableDerivedB : TestHashableBase {}
var SetTests = TestSuite("Set")
SetTests.test("contains<Hashable>(_:)") {
let s: Set<AnyHashable> = [
AnyHashable(1010 as UInt16), AnyHashable(2020), AnyHashable(3030.0)
]
for i in [1010, 2020, 3030] {
// We must be able to look up the same number in any representation.
expectTrue(s.contains(UInt16(i)))
expectTrue(s.contains(UInt32(i)))
expectTrue(s.contains(UInt64(i)))
expectTrue(s.contains(UInt(i)))
expectTrue(s.contains(Int16(i)))
expectTrue(s.contains(Int32(i)))
expectTrue(s.contains(Int64(i)))
expectTrue(s.contains(Int(i)))
expectTrue(s.contains(Float(i)))
expectTrue(s.contains(Double(i)))
expectFalse(s.contains(String(i)))
}
}
SetTests.test("index<Hashable>(of:)") {
let a = AnyHashable(1010 as UInt16)
let b = AnyHashable(2020)
let c = AnyHashable(3030.0)
let s: Set<AnyHashable> = [a, b, c]
for (element, i) in [(a, 1010), (b, 2020), (c, 3030)] {
let index = s.firstIndex(of: element)!
// We must be able to look up the same number in any representation.
expectEqual(index, s.firstIndex(of: UInt16(i)))
expectEqual(index, s.firstIndex(of: UInt32(i)))
expectEqual(index, s.firstIndex(of: UInt64(i)))
expectEqual(index, s.firstIndex(of: UInt(i)))
expectEqual(index, s.firstIndex(of: Int16(i)))
expectEqual(index, s.firstIndex(of: Int32(i)))
expectEqual(index, s.firstIndex(of: Int64(i)))
expectEqual(index, s.firstIndex(of: Int(i)))
expectEqual(index, s.firstIndex(of: Float(i)))
expectEqual(index, s.firstIndex(of: Double(i)))
}
}
SetTests.test("insert<Hashable>(_:)") {
var s: Set<AnyHashable> = [
AnyHashable(MinimalHashableValue(1010, identity: 1)),
AnyHashable(MinimalHashableValue(2020, identity: 1)),
AnyHashable(MinimalHashableClass(3030, identity: 1)),
]
do {
let (inserted, memberAfterInsert) =
s.insert(MinimalHashableValue(1010, identity: 2))
expectFalse(inserted)
expectEqual(1, memberAfterInsert.identity)
}
do {
let (inserted, memberAfterInsert) =
s.insert(MinimalHashableValue(2020, identity: 2))
expectFalse(inserted)
expectEqual(1, memberAfterInsert.identity)
}
do {
let (inserted, memberAfterInsert) =
s.insert(MinimalHashableClass(3030, identity: 2))
expectFalse(inserted)
expectEqual(1, memberAfterInsert.identity)
}
do {
let (inserted, memberAfterInsert) =
s.insert(MinimalHashableClass(1010, identity: 2))
expectTrue(inserted)
expectEqual(2, memberAfterInsert.identity)
}
do {
let (inserted, memberAfterInsert) =
s.insert(MinimalHashableClass(2020, identity: 2))
expectTrue(inserted)
expectEqual(2, memberAfterInsert.identity)
}
do {
let (inserted, memberAfterInsert) =
s.insert(MinimalHashableValue(3030, identity: 2))
expectTrue(inserted)
expectEqual(2, memberAfterInsert.identity)
}
let expected: Set<AnyHashable> = [
AnyHashable(MinimalHashableValue(1010, identity: 1)),
AnyHashable(MinimalHashableValue(2020, identity: 1)),
AnyHashable(MinimalHashableClass(3030, identity: 1)),
AnyHashable(MinimalHashableClass(1010, identity: 2)),
AnyHashable(MinimalHashableClass(2020, identity: 2)),
AnyHashable(MinimalHashableValue(3030, identity: 2)),
]
expectEqual(expected, s)
}
SetTests.test("insert<Hashable>(_:)/CastTrap")
.crashOutputMatches("Could not cast value of type 'main.TestHashableDerivedA'")
.crashOutputMatches("to 'main.TestHashableDerivedB'")
.code {
var s: Set<AnyHashable> = [
AnyHashable(TestHashableDerivedA(1010, identity: 1)),
]
do {
let (inserted, memberAfterInsert) =
s.insert(TestHashableDerivedA(1010, identity: 2))
expectFalse(inserted)
expectEqual(1, memberAfterInsert.identity)
}
expectCrashLater()
let (_, old) = s.insert(TestHashableDerivedB(1010, identity: 3))
_blackHole(old)
}
SetTests.test("update<Hashable>(with:)") {
var s: Set<AnyHashable> = [
AnyHashable(MinimalHashableValue(1010, identity: 1)),
AnyHashable(MinimalHashableValue(2020, identity: 1)),
AnyHashable(MinimalHashableClass(3030, identity: 1)),
]
do {
let old = s.update(with: MinimalHashableValue(1010, identity: 2))!
expectEqual(1, old.identity)
}
do {
let old = s.update(with: MinimalHashableValue(2020, identity: 2))!
expectEqual(1, old.identity)
}
do {
let old = s.update(with: MinimalHashableClass(3030, identity: 2))!
expectEqual(1, old.identity)
}
expectNil(s.update(with: MinimalHashableClass(1010, identity: 2)))
expectNil(s.update(with: MinimalHashableClass(2020, identity: 2)))
expectNil(s.update(with: MinimalHashableValue(3030, identity: 2)))
let expected: Set<AnyHashable> = [
AnyHashable(MinimalHashableValue(1010, identity: 2)),
AnyHashable(MinimalHashableValue(2020, identity: 2)),
AnyHashable(MinimalHashableClass(3030, identity: 2)),
AnyHashable(MinimalHashableClass(1010, identity: 2)),
AnyHashable(MinimalHashableClass(2020, identity: 2)),
AnyHashable(MinimalHashableValue(3030, identity: 2)),
]
expectEqual(expected, s)
}
SetTests.test("update<Hashable>(with:)/CastTrap")
.crashOutputMatches("Could not cast value of type 'main.TestHashableDerivedA'")
.crashOutputMatches("to 'main.TestHashableDerivedB'")
.code {
var s: Set<AnyHashable> = [
AnyHashable(TestHashableDerivedA(1010, identity: 1)),
]
do {
let old = s.update(with: TestHashableDerivedA(1010, identity: 2))!
expectEqual(1, old.identity)
}
expectCrashLater()
s.update(with: TestHashableDerivedB(1010, identity: 3))
}
SetTests.test("remove<Hashable>(_:)") {
var s: Set<AnyHashable> = [
AnyHashable(MinimalHashableValue(1010, identity: 1)),
AnyHashable(MinimalHashableValue(2020, identity: 1)),
AnyHashable(MinimalHashableClass(3030, identity: 1)),
]
expectNil(s.remove(MinimalHashableClass(1010)))
expectNil(s.remove(MinimalHashableClass(2020)))
expectNil(s.remove(MinimalHashableValue(3030)))
expectEqual(3, s.count)
do {
let old = s.remove(MinimalHashableValue(1010, identity: 2))!
expectEqual(1010, old.value)
expectEqual(1, old.identity)
}
do {
let old = s.remove(MinimalHashableValue(2020, identity: 2))!
expectEqual(2020, old.value)
expectEqual(1, old.identity)
}
do {
let old = s.remove(MinimalHashableClass(3030, identity: 2))!
expectEqual(3030, old.value)
expectEqual(1, old.identity)
}
}
SetTests.test("remove<Hashable>(_:)/CastTrap")
.crashOutputMatches("Could not cast value of type 'main.TestHashableDerivedA'")
.crashOutputMatches("to 'main.TestHashableDerivedB'")
.code {
var s: Set<AnyHashable> = [
AnyHashable(TestHashableDerivedA(1010, identity: 1)),
AnyHashable(TestHashableDerivedA(2020, identity: 1)),
]
do {
let old = s.remove(TestHashableDerivedA(1010, identity: 2))!
expectEqual(1010, old.value)
expectEqual(1, old.identity)
}
expectCrashLater()
s.remove(TestHashableDerivedB(2020, identity: 2))
}
SetTests.test("Hashable/Conversions") {
let input: [Set<AnyHashable>] = [
[10 as UInt8, 20 as UInt8, 30 as UInt8],
[10 as UInt16, 20 as UInt16, 30 as UInt16],
[10 as UInt32, 20 as UInt32, 30 as UInt32],
[10 as UInt64, 20 as UInt64, 30 as UInt64],
[10 as UInt, 20 as UInt, 30 as UInt],
[10 as Int8, 20 as Int8, 30 as Int8],
[10 as Int16, 20 as Int16, 30 as Int16],
[10 as Int32, 20 as Int32, 30 as Int32],
[10 as Int64, 20 as Int64, 30 as Int64],
[10 as Int, 20 as Int, 30 as Int],
[10 as Float, 20 as Float, 30 as Float],
[10 as Double, 20 as Double, 30 as Double],
[[1, 2, 3] as Set<Int>, [2, 3, 4] as Set<UInt8>, [3, 4, 5] as Set<Float>],
[[1, 2, 3] as Set<Int8>, [2, 3, 4] as Set<Double>, [3, 4, 5] as Set<Int32>],
[[1, 2, 3] as Set<UInt32>, [2, 3, 4] as Set<Int16>, [3, 4, 5] as Set<UInt>],
]
checkHashable(input, equalityOracle: { ($0 < 12) == ($1 < 12) })
}
runAllTests()