// RUN: %target-run-simple-swift // REQUIRES: executable_test import StdlibUnittest class TestHashableBase : Hashable { var value: Int var identity: Int init(_ value: Int, identity: Int) { self.value = value self.identity = identity } var hashValue: Int { return 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(_:)") { let s: Set = [ 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(of:)") { let a = AnyHashable(1010 as UInt16) let b = AnyHashable(2020) let c = AnyHashable(3030.0) let s: Set = [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(_:)") { var s: Set = [ 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(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(_:)/FormerCastTrap") { var s: Set = [ AnyHashable(TestHashableDerivedA(1010, identity: 1)), ] do { let (inserted, memberAfterInsert) = s.insert(TestHashableDerivedA(1010, identity: 2)) expectFalse(inserted) expectEqual(1, memberAfterInsert.identity) } _ = s.insert(TestHashableDerivedB(1010, identity: 3)) } SetTests.test("update(with:)") { var s: Set = [ 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(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(with:)/FormerCastTrap") { var s: Set = [ AnyHashable(TestHashableDerivedA(1010, identity: 1)), ] do { let old = s.update(with: TestHashableDerivedA(1010, identity: 2))! expectEqual(1, old.identity) } s.update(with: TestHashableDerivedB(1010, identity: 3)) } SetTests.test("remove(_:)") { var s: Set = [ 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(_:)/FormerCastTrap") { var s: Set = [ 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) } s.remove(TestHashableDerivedB(2020, identity: 2)) } SetTests.test("Hashable/Conversions") { let input: [Set] = [ [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, [2, 3, 4] as Set, [3, 4, 5] as Set], [[1, 2, 3] as Set, [2, 3, 4] as Set, [3, 4, 5] as Set], [[1, 2, 3] as Set, [2, 3, 4] as Set, [3, 4, 5] as Set], ] checkHashable(input, equalityOracle: { ($0 < 12) == ($1 < 12) }) } runAllTests()