blob: e386aac363a1fd963cfeff8f2e3bfb248e47a019 [file] [log] [blame]
// RUN: %empty-directory(%t)
//
// RUN: %gyb %s -o %t/Runtime.swift
// RUN: %target-build-swift -parse-stdlib -module-name a %t/Runtime.swift -o %t.out
// RUN: %target-run %t.out
// REQUIRES: executable_test
import Swift
import StdlibUnittest
import SwiftShims
#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
import Darwin
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
import Glibc
#endif
@_silgen_name("swift_demangle")
public
func _stdlib_demangleImpl(
mangledName: UnsafePointer<CChar>?,
mangledNameLength: UInt,
outputBuffer: UnsafeMutablePointer<CChar>?,
outputBufferSize: UnsafeMutablePointer<UInt>?,
flags: UInt32
) -> UnsafeMutablePointer<CChar>?
func _stdlib_demangleName(_ mangledName: String) -> String {
return mangledName.utf8CString.withUnsafeBufferPointer {
(mangledNameUTF8CStr) in
let demangledNamePtr = _stdlib_demangleImpl(
mangledName: mangledNameUTF8CStr.baseAddress,
mangledNameLength: UInt(mangledNameUTF8CStr.count - 1),
outputBuffer: nil,
outputBufferSize: nil,
flags: 0)
if let demangledNamePtr = demangledNamePtr {
let demangledName = String(cString: demangledNamePtr)
_stdlib_free(demangledNamePtr)
return demangledName
}
return mangledName
}
}
var swiftObjectCanaryCount = 0
class SwiftObjectCanary {
init() {
swiftObjectCanaryCount += 1
}
deinit {
swiftObjectCanaryCount -= 1
}
}
struct SwiftObjectCanaryStruct {
var ref = SwiftObjectCanary()
}
var Runtime = TestSuite("Runtime")
Runtime.test("_canBeClass") {
expectEqual(1, _canBeClass(SwiftObjectCanary.self))
expectEqual(0, _canBeClass(SwiftObjectCanaryStruct.self))
typealias SwiftClosure = () -> ()
expectEqual(0, _canBeClass(SwiftClosure.self))
}
//===----------------------------------------------------------------------===//
// The protocol should be defined in the standard library, otherwise the cast
// does not work.
typealias P1 = CustomReflectable
typealias P2 = CustomStringConvertible
protocol Q1 {}
extension P1 {
var success: Bool {
print(String(describing: customMirror))
return String(describing: customMirror) == "Mirror for ()"
}
}
// A small struct that can be stored inline in an opaque buffer.
struct StructConformsToP1 : CustomReflectable, Q1 {
var customMirror: Mirror {
return Mirror(reflecting: ())
}
}
// A small struct that can be stored inline in an opaque buffer.
struct Struct2ConformsToP1<T : CustomReflectable> : CustomReflectable, Q1 {
init(_ value: T) {
self.value = value
}
var customMirror: Mirror {
return value.customMirror
}
var value: T
}
// A large struct that cannot be stored inline in an opaque buffer.
struct Struct3ConformsToP2 : CustomStringConvertible, Q1 {
var a: UInt64 = 10
var b: UInt64 = 20
var c: UInt64 = 30
var d: UInt64 = 40
var description: String {
// Don't rely on string interpolation, it uses the casts that we are trying
// to test.
var result = ""
result += _uint64ToString(a) + " "
result += _uint64ToString(b) + " "
result += _uint64ToString(c) + " "
result += _uint64ToString(d)
return result
}
}
// A large struct that cannot be stored inline in an opaque buffer.
struct Struct4ConformsToP2<T : CustomStringConvertible> : CustomStringConvertible, Q1 {
var value: T
var e: UInt64 = 50
var f: UInt64 = 60
var g: UInt64 = 70
var h: UInt64 = 80
init(_ value: T) {
self.value = value
}
var description: String {
// Don't rely on string interpolation, it uses the casts that we are trying
// to test.
var result = value.description + " "
result += _uint64ToString(e) + " "
result += _uint64ToString(f) + " "
result += _uint64ToString(g) + " "
result += _uint64ToString(h)
return result
}
}
struct StructDoesNotConformToP1 : Q1 {}
class ClassConformsToP1 : CustomReflectable, Q1 {
var customMirror: Mirror {
return Mirror(reflecting: ())
}
}
class Class2ConformsToP1<T : CustomReflectable> : CustomReflectable, Q1 {
init(_ value: T) {
self.value = [value]
}
var customMirror: Mirror {
return value[0].customMirror
}
// FIXME: should be "var value: T", but we don't support it now.
var value: Array<T>
}
class ClassDoesNotConformToP1 : Q1 {}
Runtime.test("dynamicCasting with as") {
var someP1Value = StructConformsToP1()
var someP1Value2 = Struct2ConformsToP1(StructConformsToP1())
var someNotP1Value = StructDoesNotConformToP1()
var someP2Value = Struct3ConformsToP2()
var someP2Value2 = Struct4ConformsToP2(Struct3ConformsToP2())
var someP1Ref = ClassConformsToP1()
var someP1Ref2 = Class2ConformsToP1(ClassConformsToP1())
var someNotP1Ref = ClassDoesNotConformToP1()
expectTrue(someP1Value is P1)
expectTrue(someP1Value2 is P1)
expectFalse(someNotP1Value is P1)
expectTrue(someP2Value is P2)
expectTrue(someP2Value2 is P2)
expectTrue(someP1Ref is P1)
expectTrue(someP1Ref2 is P1)
expectFalse(someNotP1Ref is P1)
expectTrue(someP1Value as P1 is P1)
expectTrue(someP1Value2 as P1 is P1)
expectTrue(someP2Value as P2 is P2)
expectTrue(someP2Value2 as P2 is P2)
expectTrue(someP1Ref as P1 is P1)
expectTrue(someP1Value as Q1 is P1)
expectTrue(someP1Value2 as Q1 is P1)
expectFalse(someNotP1Value as Q1 is P1)
expectTrue(someP2Value as Q1 is P2)
expectTrue(someP2Value2 as Q1 is P2)
expectTrue(someP1Ref as Q1 is P1)
expectTrue(someP1Ref2 as Q1 is P1)
expectFalse(someNotP1Ref as Q1 is P1)
expectTrue(someP1Value as Any is P1)
expectTrue(someP1Value2 as Any is P1)
expectFalse(someNotP1Value as Any is P1)
expectTrue(someP2Value as Any is P2)
expectTrue(someP2Value2 as Any is P2)
expectTrue(someP1Ref as Any is P1)
expectTrue(someP1Ref2 as Any is P1)
expectFalse(someNotP1Ref as Any is P1)
expectTrue(someP1Ref as AnyObject is P1)
expectTrue(someP1Ref2 as AnyObject is P1)
expectFalse(someNotP1Ref as AnyObject is P1)
expectTrue((someP1Value as P1).success)
expectTrue((someP1Value2 as P1).success)
expectEqual("10 20 30 40", (someP2Value as P2).description)
expectEqual("10 20 30 40 50 60 70 80", (someP2Value2 as P2).description)
expectTrue((someP1Ref as P1).success)
expectTrue((someP1Ref2 as P1).success)
expectTrue(((someP1Value as Q1) as! P1).success)
expectTrue(((someP1Value2 as Q1) as! P1).success)
expectEqual("10 20 30 40", ((someP2Value as Q1) as! P2).description)
expectEqual("10 20 30 40 50 60 70 80",
((someP2Value2 as Q1) as! P2).description)
expectTrue(((someP1Ref as Q1) as! P1).success)
expectTrue(((someP1Ref2 as Q1) as! P1).success)
expectTrue(((someP1Value as Any) as! P1).success)
expectTrue(((someP1Value2 as Any) as! P1).success)
expectEqual("10 20 30 40", ((someP2Value as Any) as! P2).description)
expectEqual("10 20 30 40 50 60 70 80",
((someP2Value2 as Any) as! P2).description)
expectTrue(((someP1Ref as Any) as! P1).success)
expectTrue(((someP1Ref2 as Any) as! P1).success)
expectTrue(((someP1Ref as AnyObject) as! P1).success)
expectNil((someNotP1Value as? P1))
expectNil((someNotP1Ref as? P1))
expectTrue(((someP1Value as Q1) as? P1)!.success)
expectTrue(((someP1Value2 as Q1) as? P1)!.success)
expectNil(((someNotP1Value as Q1) as? P1))
expectEqual("10 20 30 40", ((someP2Value as Q1) as? P2)!.description)
expectEqual("10 20 30 40 50 60 70 80",
((someP2Value2 as Q1) as? P2)!.description)
expectTrue(((someP1Ref as Q1) as? P1)!.success)
expectTrue(((someP1Ref2 as Q1) as? P1)!.success)
expectNil(((someNotP1Ref as Q1) as? P1))
expectTrue(((someP1Value as Any) as? P1)!.success)
expectTrue(((someP1Value2 as Any) as? P1)!.success)
expectNil(((someNotP1Value as Any) as? P1))
expectEqual("10 20 30 40", ((someP2Value as Any) as? P2)!.description)
expectEqual("10 20 30 40 50 60 70 80",
((someP2Value2 as Any) as? P2)!.description)
expectTrue(((someP1Ref as Any) as? P1)!.success)
expectTrue(((someP1Ref2 as Any) as? P1)!.success)
expectNil(((someNotP1Ref as Any) as? P1))
expectTrue(((someP1Ref as AnyObject) as? P1)!.success)
expectTrue(((someP1Ref2 as AnyObject) as? P1)!.success)
expectNil(((someNotP1Ref as AnyObject) as? P1))
let doesThrow: (Int) throws -> Int = { $0 }
let doesNotThrow: (String) -> String = { $0 }
var any: Any = doesThrow
expectTrue(doesThrow as Any is (Int) throws -> Int)
expectFalse(doesThrow as Any is (String) throws -> Int)
expectFalse(doesThrow as Any is (String) throws -> String)
expectFalse(doesThrow as Any is (Int) throws -> String)
expectFalse(doesThrow as Any is (Int) -> Int)
expectFalse(doesThrow as Any is (String) throws -> String)
expectFalse(doesThrow as Any is (String) -> String)
expectTrue(doesNotThrow as Any is (String) throws -> String)
expectTrue(doesNotThrow as Any is (String) -> String)
expectFalse(doesNotThrow as Any is (Int) -> String)
expectFalse(doesNotThrow as Any is (Int) -> Int)
expectFalse(doesNotThrow as Any is (String) -> Int)
expectFalse(doesNotThrow as Any is (Int) throws -> Int)
expectFalse(doesNotThrow as Any is (Int) -> Int)
}
extension Int {
class ExtensionClassConformsToP2 : P2 {
var description: String { return "abc" }
}
fileprivate class PrivateExtensionClassConformsToP2 : P2 {
var description: String { return "def" }
}
}
Runtime.test("dynamic cast to existential with cross-module extensions") {
let internalObj = Int.ExtensionClassConformsToP2()
let privateObj = Int.PrivateExtensionClassConformsToP2()
expectTrue(internalObj is P2)
expectTrue(privateObj is P2)
}
class SomeClass {}
struct SomeStruct {}
enum SomeEnum {
case A
init() { self = .A }
}
Runtime.test("typeName") {
expectEqual("a.SomeClass", _typeName(SomeClass.self))
expectEqual("a.SomeStruct", _typeName(SomeStruct.self))
expectEqual("a.SomeEnum", _typeName(SomeEnum.self))
expectEqual("Any.Protocol", _typeName(Any.Protocol.self))
expectEqual("Swift.AnyObject.Protocol", _typeName(AnyObject.Protocol.self))
expectEqual("Swift.AnyObject.Type.Protocol", _typeName(AnyClass.Protocol.self))
expectEqual("Swift.Optional<Swift.AnyObject>.Type", _typeName((AnyObject?).Type.self))
var a: Any = SomeClass()
expectEqual("a.SomeClass", _typeName(type(of: a)))
a = SomeStruct()
expectEqual("a.SomeStruct", _typeName(type(of: a)))
a = SomeEnum()
expectEqual("a.SomeEnum", _typeName(type(of: a)))
a = AnyObject.self
expectEqual("Swift.AnyObject.Protocol", _typeName(type(of: a)))
a = AnyClass.self
expectEqual("Swift.AnyObject.Type.Protocol", _typeName(type(of: a)))
a = (AnyObject?).self
expectEqual("Swift.Optional<Swift.AnyObject>.Type",
_typeName(type(of: a)))
a = Any.self
expectEqual("Any.Protocol", _typeName(type(of: a)))
}
class SomeSubclass : SomeClass {}
protocol SomeProtocol {}
class SomeConformingClass : SomeProtocol {}
class SomeConformingSubclass : SomeConformingClass {}
class UnicodeCläss {}
Runtime.test("typeByName") {
expectTrue(_typeByName("a.SomeClass") == SomeClass.self)
expectTrue(_typeByName("a.SomeSubclass") == SomeSubclass.self)
// name lookup will be via protocol conformance table
expectTrue(_typeByName("a.SomeConformingClass") == SomeConformingClass.self)
expectTrue(_typeByName("a.UnicodeCläss") == UnicodeCläss.self)
}
Runtime.test("demangleName") {
expectEqual("", _stdlib_demangleName(""))
expectEqual("abc", _stdlib_demangleName("abc"))
expectEqual("\0", _stdlib_demangleName("\0"))
expectEqual("Swift.Double", _stdlib_demangleName("$SSdD"))
expectEqual("x.a : x.Foo<x.Foo<x.Foo<Swift.Int, Swift.Int>, x.Foo<Swift.Int, Swift.Int>>, x.Foo<x.Foo<Swift.Int, Swift.Int>, x.Foo<Swift.Int, Swift.Int>>>",
_stdlib_demangleName("$S1x1aAA3FooCyADyADySiSiGADySiSiGGADyADySiSiGADySiSiGGGvp"))
expectEqual("Foobar", _stdlib_demangleName("$S13__lldb_expr_46FoobarCD"))
}
% for optionality in ['', '?']:
Runtime.test("_stdlib_atomicCompareExchangeStrongPtr") {
typealias IntPtr = UnsafeMutablePointer<Int>
var origP1: IntPtr${optionality} = IntPtr(bitPattern: 0x10101010)!
var origP2: IntPtr${optionality} = IntPtr(bitPattern: 0x20202020)!
var origP3: IntPtr${optionality} = IntPtr(bitPattern: 0x30303030)!
do {
var object = origP1
var expected = origP1
let r = _stdlib_atomicCompareExchangeStrongPtr(
object: &object, expected: &expected, desired: origP2)
expectTrue(r)
expectEqual(origP2, object)
expectEqual(origP1, expected)
}
do {
var object = origP1
var expected = origP2
let r = _stdlib_atomicCompareExchangeStrongPtr(
object: &object, expected: &expected, desired: origP3)
expectFalse(r)
expectEqual(origP1, object)
expectEqual(origP1, expected)
}
struct FooStruct {
var i: Int
var object: IntPtr${optionality}
var expected: IntPtr${optionality}
init(object: IntPtr${optionality}, expected: IntPtr${optionality}) {
self.i = 0
self.object = object
self.expected = expected
}
}
do {
var foo = FooStruct(object: origP1, expected: origP1)
let r = _stdlib_atomicCompareExchangeStrongPtr(
object: &foo.object, expected: &foo.expected, desired: origP2)
expectTrue(r)
expectEqual(origP2, foo.object)
expectEqual(origP1, foo.expected)
}
do {
var foo = FooStruct(object: origP1, expected: origP2)
let r = _stdlib_atomicCompareExchangeStrongPtr(
object: &foo.object, expected: &foo.expected, desired: origP3)
expectFalse(r)
expectEqual(origP1, foo.object)
expectEqual(origP1, foo.expected)
}
}
% end
Runtime.test("casting AnyObject to class metatypes") {
do {
var ao: AnyObject = SomeClass()
expectTrue(ao as? Any.Type == nil)
expectTrue(ao as? AnyClass == nil)
}
do {
var a: Any = SomeClass()
expectTrue(a as? Any.Type == nil)
expectTrue(a as? AnyClass == nil)
a = SomeClass.self
expectTrue(a as? Any.Type == SomeClass.self)
expectTrue(a as? AnyClass == SomeClass.self)
expectTrue(a as? SomeClass.Type == SomeClass.self)
}
}
func wantonlyWrapInAny<T>(_ x: T) -> Any {
return x
}
// Because `type(of: x)` and `T.self` have the same type `T.Type` in
// a <T>(x: T) context, both operations must produce the concrete protocol
// type value when `T` is bound to an existential type `P`.
func castWithAbstractionBarrier<T>(_ x: T) -> (
staticWithConcreteType: T.Type,
dynamicWithConcreteType: T.Type,
staticWithErasedType: Any.Type,
dynamicWithErasedType: Any.Type,
dynamicExistentialWithErasedType: Any.Type,
dynamicDoubleWrappedExistentialWithErasedType: Any.Type
) {
return (
staticWithConcreteType: T.self,
dynamicWithConcreteType: type(of: x),
staticWithErasedType: T.self,
dynamicWithErasedType: type(of: x),
dynamicExistentialWithErasedType: type(of: x as Any),
dynamicDoubleWrappedExistentialWithErasedType:
type(of: wantonlyWrapInAny(wantonlyWrapInAny(x)))
)
}
Runtime.test("abstraction barrier on casting generic param bound to existential") {
let c: SomeConformingClass = SomeConformingSubclass()
let x: SomeProtocol = c
let (staticWithConcreteType,
dynamicWithConcreteType,
staticWithErasedType,
dynamicWithErasedType,
dynamicExistentialWithErasedType,
dynamicDoubleWrappedExistentialWithErasedType)
= castWithAbstractionBarrier(x)
expectTrue(staticWithConcreteType == SomeProtocol.self)
expectTrue(dynamicWithConcreteType == SomeProtocol.self)
expectTrue(staticWithErasedType == SomeProtocol.self)
expectTrue(dynamicWithErasedType == SomeProtocol.self)
// type(of: x as Any) can be a proper existential type cast
expectTrue(dynamicExistentialWithErasedType == SomeConformingSubclass.self)
expectTrue(dynamicDoubleWrappedExistentialWithErasedType
== SomeConformingSubclass.self)
}
class Malkovich: Malkovichable {
var malkovich: String { return "malkovich" }
}
protocol Malkovichable: class {
var malkovich: String { get }
}
struct GenericStructWithReferenceStorage<T> {
var a: T
unowned(safe) var unownedConcrete: Malkovich
unowned(unsafe) var unmanagedConcrete: Malkovich
weak var weakConcrete: Malkovich?
unowned(safe) var unownedProto: Malkovichable
unowned(unsafe) var unmanagedProto: Malkovichable
weak var weakProto: Malkovichable?
}
func exerciseReferenceStorageInGenericContext<T>(
_ x: GenericStructWithReferenceStorage<T>,
forceCopy y: GenericStructWithReferenceStorage<T>
) {
expectEqual(x.unownedConcrete.malkovich, "malkovich")
expectEqual(x.unmanagedConcrete.malkovich, "malkovich")
expectEqual(x.weakConcrete!.malkovich, "malkovich")
expectEqual(x.unownedProto.malkovich, "malkovich")
expectEqual(x.unmanagedProto.malkovich, "malkovich")
expectEqual(x.weakProto!.malkovich, "malkovich")
expectEqual(y.unownedConcrete.malkovich, "malkovich")
expectEqual(y.unmanagedConcrete.malkovich, "malkovich")
expectEqual(y.weakConcrete!.malkovich, "malkovich")
expectEqual(y.unownedProto.malkovich, "malkovich")
expectEqual(y.unmanagedProto.malkovich, "malkovich")
expectEqual(y.weakProto!.malkovich, "malkovich")
}
Runtime.test("Struct layout with reference storage types") {
let malkovich = Malkovich()
let x = GenericStructWithReferenceStorage(a: malkovich,
unownedConcrete: malkovich,
unmanagedConcrete: malkovich,
weakConcrete: malkovich,
unownedProto: malkovich,
unmanagedProto: malkovich,
weakProto: malkovich)
exerciseReferenceStorageInGenericContext(x, forceCopy: x)
expectEqual(x.unownedConcrete.malkovich, "malkovich")
expectEqual(x.unmanagedConcrete.malkovich, "malkovich")
expectEqual(x.weakConcrete!.malkovich, "malkovich")
expectEqual(x.unownedProto.malkovich, "malkovich")
expectEqual(x.unmanagedProto.malkovich, "malkovich")
expectEqual(x.weakProto!.malkovich, "malkovich")
// Make sure malkovich lives long enough.
print(malkovich)
}
Runtime.test("SwiftError layout constants for LLDB") {
#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: -2)
#elseif os(Linux)
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: 0)
#else
_UnimplementedError()
#endif
let offsetof_SwiftError_typeMetadata =
dlsym(RTLD_DEFAULT, "_swift_lldb_offsetof_SwiftError_typeMetadata")!
let sizeof_SwiftError =
dlsym(RTLD_DEFAULT, "_swift_lldb_sizeof_SwiftError")!
#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
#if arch(i386) || arch(arm)
expectEqual(20, offsetof_SwiftError_typeMetadata.load(as: UInt.self))
expectEqual(36, sizeof_SwiftError.load(as: UInt.self))
#else
expectEqual(40, offsetof_SwiftError_typeMetadata.load(as: UInt.self))
expectEqual(72, sizeof_SwiftError.load(as: UInt.self))
#endif
#elseif os(Linux)
expectEqual(16, offsetof_SwiftError_typeMetadata.load(as: UInt.self))
expectEqual(32, sizeof_SwiftError.load(as: UInt.self))
#else
_UnimplementedError()
#endif
}
var Reflection = TestSuite("Reflection")
func wrap1 (_ x: Any) -> Any { return x }
func wrap2<T>(_ x: T) -> Any { return wrap1(x) }
func wrap3 (_ x: Any) -> Any { return wrap2(x) }
func wrap4<T>(_ x: T) -> Any { return wrap3(x) }
func wrap5 (_ x: Any) -> Any { return wrap4(x) }
class JustNeedAMetatype {}
Reflection.test("nested existential containers") {
let wrapped = wrap5(JustNeedAMetatype.self)
expectEqual("\(wrapped)", "JustNeedAMetatype")
}
Reflection.test("dumpToAStream") {
var output = ""
dump([ 42, 4242 ], to: &output)
expectEqual("â–¿ 2 elements\n - 42\n - 4242\n", output)
}
struct StructWithDefaultMirror {
let s: String
init (_ s: String) {
self.s = s
}
}
Reflection.test("Struct/NonGeneric/DefaultMirror") {
do {
var output = ""
dump(StructWithDefaultMirror("123"), to: &output)
expectEqual("â–¿ a.StructWithDefaultMirror\n - s: \"123\"\n", output)
}
do {
// Build a String around an interpolation as a way of smoke-testing that
// the internal _Mirror implementation gets memory management right.
var output = ""
dump(StructWithDefaultMirror("\(456)"), to: &output)
expectEqual("â–¿ a.StructWithDefaultMirror\n - s: \"456\"\n", output)
}
expectEqual(
.`struct`,
Mirror(reflecting: StructWithDefaultMirror("")).displayStyle)
}
struct GenericStructWithDefaultMirror<T, U> {
let first: T
let second: U
}
Reflection.test("Struct/Generic/DefaultMirror") {
do {
var value = GenericStructWithDefaultMirror<Int, [Any?]>(
first: 123,
second: ["abc", 456, 789.25])
var output = ""
dump(value, to: &output)
let expected =
"â–¿ a.GenericStructWithDefaultMirror<Swift.Int, Swift.Array<Swift.Optional<Any>>>\n" +
" - first: 123\n" +
" â–¿ second: 3 elements\n" +
" â–¿ Optional(\"abc\")\n" +
" - some: \"abc\"\n" +
" â–¿ Optional(456)\n" +
" - some: 456\n" +
" â–¿ Optional(789.25)\n" +
" - some: 789.25\n"
expectEqual(expected, output)
}
}
enum NoPayloadEnumWithDefaultMirror {
case A, ß
}
Reflection.test("Enum/NoPayload/DefaultMirror") {
do {
let value: [NoPayloadEnumWithDefaultMirror] =
[.A, .ß]
var output = ""
dump(value, to: &output)
let expected =
"â–¿ 2 elements\n" +
" - a.NoPayloadEnumWithDefaultMirror.A\n" +
" - a.NoPayloadEnumWithDefaultMirror.ß\n"
expectEqual(expected, output)
}
}
enum SingletonNonGenericEnumWithDefaultMirror {
case OnlyOne(Int)
}
Reflection.test("Enum/SingletonNonGeneric/DefaultMirror") {
do {
let value = SingletonNonGenericEnumWithDefaultMirror.OnlyOne(5)
var output = ""
dump(value, to: &output)
let expected =
"â–¿ a.SingletonNonGenericEnumWithDefaultMirror.OnlyOne\n" +
" - OnlyOne: 5\n"
expectEqual(expected, output)
}
}
enum SingletonGenericEnumWithDefaultMirror<T> {
case OnlyOne(T)
}
Reflection.test("Enum/SingletonGeneric/DefaultMirror") {
do {
let value = SingletonGenericEnumWithDefaultMirror.OnlyOne("IIfx")
var output = ""
dump(value, to: &output)
let expected =
"â–¿ a.SingletonGenericEnumWithDefaultMirror<Swift.String>.OnlyOne\n" +
" - OnlyOne: \"IIfx\"\n"
expectEqual(expected, output)
}
expectEqual(0, LifetimeTracked.instances)
do {
let value = SingletonGenericEnumWithDefaultMirror.OnlyOne(
LifetimeTracked(0))
expectEqual(1, LifetimeTracked.instances)
var output = ""
dump(value, to: &output)
}
expectEqual(0, LifetimeTracked.instances)
}
enum SinglePayloadNonGenericEnumWithDefaultMirror {
case Cat
case Dog
case Volleyball(String, Int)
}
Reflection.test("Enum/SinglePayloadNonGeneric/DefaultMirror") {
do {
let value: [SinglePayloadNonGenericEnumWithDefaultMirror] =
[.Cat,
.Dog,
.Volleyball("Wilson", 2000)]
var output = ""
dump(value, to: &output)
let expected =
"â–¿ 3 elements\n" +
" - a.SinglePayloadNonGenericEnumWithDefaultMirror.Cat\n" +
" - a.SinglePayloadNonGenericEnumWithDefaultMirror.Dog\n" +
" â–¿ a.SinglePayloadNonGenericEnumWithDefaultMirror.Volleyball\n" +
" â–¿ Volleyball: (2 elements)\n" +
" - .0: \"Wilson\"\n" +
" - .1: 2000\n"
expectEqual(expected, output)
}
}
enum SinglePayloadGenericEnumWithDefaultMirror<T, U> {
case Well
case Faucet
case Pipe(T, U)
}
Reflection.test("Enum/SinglePayloadGeneric/DefaultMirror") {
do {
let value: [SinglePayloadGenericEnumWithDefaultMirror<Int, [Int]>] =
[.Well,
.Faucet,
.Pipe(408, [415])]
var output = ""
dump(value, to: &output)
let expected =
"â–¿ 3 elements\n" +
" - a.SinglePayloadGenericEnumWithDefaultMirror<Swift.Int, Swift.Array<Swift.Int>>.Well\n" +
" - a.SinglePayloadGenericEnumWithDefaultMirror<Swift.Int, Swift.Array<Swift.Int>>.Faucet\n" +
" â–¿ a.SinglePayloadGenericEnumWithDefaultMirror<Swift.Int, Swift.Array<Swift.Int>>.Pipe\n" +
" â–¿ Pipe: (2 elements)\n" +
" - .0: 408\n" +
" â–¿ .1: 1 element\n" +
" - 415\n"
expectEqual(expected, output)
}
}
enum MultiPayloadTagBitsNonGenericEnumWithDefaultMirror {
case Plus
case SE30
case Classic(mhz: Int)
case Performa(model: Int)
}
Reflection.test("Enum/MultiPayloadTagBitsNonGeneric/DefaultMirror") {
do {
let value: [MultiPayloadTagBitsNonGenericEnumWithDefaultMirror] =
[.Plus,
.SE30,
.Classic(mhz: 16),
.Performa(model: 220)]
var output = ""
dump(value, to: &output)
let expected =
"â–¿ 4 elements\n" +
" - a.MultiPayloadTagBitsNonGenericEnumWithDefaultMirror.Plus\n" +
" - a.MultiPayloadTagBitsNonGenericEnumWithDefaultMirror.SE30\n" +
" â–¿ a.MultiPayloadTagBitsNonGenericEnumWithDefaultMirror.Classic\n" +
" â–¿ Classic: (1 element)\n" +
" - mhz: 16\n" +
" â–¿ a.MultiPayloadTagBitsNonGenericEnumWithDefaultMirror.Performa\n" +
" â–¿ Performa: (1 element)\n" +
" - model: 220\n"
expectEqual(expected, output)
}
}
class Floppy {
let capacity: Int
init(capacity: Int) { self.capacity = capacity }
}
class CDROM {
let capacity: Int
init(capacity: Int) { self.capacity = capacity }
}
enum MultiPayloadSpareBitsNonGenericEnumWithDefaultMirror {
case MacWrite
case MacPaint
case FileMaker
case ClarisWorks(floppy: Floppy)
case HyperCard(cdrom: CDROM)
}
Reflection.test("Enum/MultiPayloadSpareBitsNonGeneric/DefaultMirror") {
do {
let value: [MultiPayloadSpareBitsNonGenericEnumWithDefaultMirror] =
[.MacWrite,
.MacPaint,
.FileMaker,
.ClarisWorks(floppy: Floppy(capacity: 800)),
.HyperCard(cdrom: CDROM(capacity: 600))]
var output = ""
dump(value, to: &output)
let expected =
"â–¿ 5 elements\n" +
" - a.MultiPayloadSpareBitsNonGenericEnumWithDefaultMirror.MacWrite\n" +
" - a.MultiPayloadSpareBitsNonGenericEnumWithDefaultMirror.MacPaint\n" +
" - a.MultiPayloadSpareBitsNonGenericEnumWithDefaultMirror.FileMaker\n" +
" â–¿ a.MultiPayloadSpareBitsNonGenericEnumWithDefaultMirror.ClarisWorks\n" +
" â–¿ ClarisWorks: (1 element)\n" +
" â–¿ floppy: a.Floppy #0\n" +
" - capacity: 800\n" +
" â–¿ a.MultiPayloadSpareBitsNonGenericEnumWithDefaultMirror.HyperCard\n" +
" â–¿ HyperCard: (1 element)\n" +
" â–¿ cdrom: a.CDROM #1\n" +
" - capacity: 600\n"
expectEqual(expected, output)
}
}
enum MultiPayloadTagBitsSmallNonGenericEnumWithDefaultMirror {
case MacWrite
case MacPaint
case FileMaker
case ClarisWorks(floppy: Bool)
case HyperCard(cdrom: Bool)
}
Reflection.test("Enum/MultiPayloadTagBitsSmallNonGeneric/DefaultMirror") {
do {
let value: [MultiPayloadTagBitsSmallNonGenericEnumWithDefaultMirror] =
[.MacWrite,
.MacPaint,
.FileMaker,
.ClarisWorks(floppy: true),
.HyperCard(cdrom: false)]
var output = ""
dump(value, to: &output)
let expected =
"â–¿ 5 elements\n" +
" - a.MultiPayloadTagBitsSmallNonGenericEnumWithDefaultMirror.MacWrite\n" +
" - a.MultiPayloadTagBitsSmallNonGenericEnumWithDefaultMirror.MacPaint\n" +
" - a.MultiPayloadTagBitsSmallNonGenericEnumWithDefaultMirror.FileMaker\n" +
" â–¿ a.MultiPayloadTagBitsSmallNonGenericEnumWithDefaultMirror.ClarisWorks\n" +
" â–¿ ClarisWorks: (1 element)\n" +
" - floppy: true\n" +
" â–¿ a.MultiPayloadTagBitsSmallNonGenericEnumWithDefaultMirror.HyperCard\n" +
" â–¿ HyperCard: (1 element)\n" +
" - cdrom: false\n"
expectEqual(expected, output)
}
}
enum MultiPayloadGenericEnumWithDefaultMirror<T, U> {
case IIe
case IIgs
case Centris(ram: T)
case Quadra(hdd: U)
case PowerBook170
case PowerBookDuo220
}
Reflection.test("Enum/MultiPayloadGeneric/DefaultMirror") {
do {
let value: [MultiPayloadGenericEnumWithDefaultMirror<Int, String>] =
[.IIe,
.IIgs,
.Centris(ram: 4096),
.Quadra(hdd: "160MB"),
.PowerBook170,
.PowerBookDuo220]
var output = ""
dump(value, to: &output)
let expected =
"â–¿ 6 elements\n" +
" - a.MultiPayloadGenericEnumWithDefaultMirror<Swift.Int, Swift.String>.IIe\n" +
" - a.MultiPayloadGenericEnumWithDefaultMirror<Swift.Int, Swift.String>.IIgs\n" +
" â–¿ a.MultiPayloadGenericEnumWithDefaultMirror<Swift.Int, Swift.String>.Centris\n" +
" â–¿ Centris: (1 element)\n" +
" - ram: 4096\n" +
" â–¿ a.MultiPayloadGenericEnumWithDefaultMirror<Swift.Int, Swift.String>.Quadra\n" +
" â–¿ Quadra: (1 element)\n" +
" - hdd: \"160MB\"\n" +
" - a.MultiPayloadGenericEnumWithDefaultMirror<Swift.Int, Swift.String>.PowerBook170\n" +
" - a.MultiPayloadGenericEnumWithDefaultMirror<Swift.Int, Swift.String>.PowerBookDuo220\n"
expectEqual(expected, output)
}
expectEqual(0, LifetimeTracked.instances)
do {
let value = MultiPayloadGenericEnumWithDefaultMirror<LifetimeTracked,
LifetimeTracked>
.Quadra(hdd: LifetimeTracked(0))
expectEqual(1, LifetimeTracked.instances)
var output = ""
dump(value, to: &output)
}
expectEqual(0, LifetimeTracked.instances)
}
enum Foo<T> {
indirect case Foo(Int)
case Bar(T)
}
enum List<T> {
case Nil
indirect case Cons(first: T, rest: List<T>)
}
Reflection.test("Enum/IndirectGeneric/DefaultMirror") {
let x = Foo<String>.Foo(22)
let y = Foo<String>.Bar("twenty-two")
expectEqual("\(x)", "Foo(22)")
expectEqual("\(y)", "Bar(\"twenty-two\")")
let list = List.Cons(first: 0, rest: .Cons(first: 1, rest: .Nil))
expectEqual("Cons(first: 0, rest: a.List<Swift.Int>.Cons(first: 1, rest: a.List<Swift.Int>.Nil))",
"\(list)")
}
enum MyError: Error {
case myFirstError(LifetimeTracked)
}
Reflection.test("Enum/CaseName/Error") {
// Just make sure this doesn't leak.
let e: Error = MyError.myFirstError(LifetimeTracked(0))
_ = String(describing: e)
}
class Brilliant : CustomReflectable {
let first: Int
let second: String
init(_ fst: Int, _ snd: String) {
self.first = fst
self.second = snd
}
var customMirror: Mirror {
return Mirror(self, children: ["first": first, "second": second, "self": self])
}
}
/// Subclasses inherit their parents' custom mirrors.
class Irradiant : Brilliant {
init() {
super.init(400, "")
}
}
Reflection.test("CustomMirror") {
do {
var output = ""
dump(Brilliant(123, "four five six"), to: &output)
let expected =
"â–¿ a.Brilliant #0\n" +
" - first: 123\n" +
" - second: \"four five six\"\n" +
" â–¿ self: a.Brilliant #0\n"
expectEqual(expected, output)
}
do {
var output = ""
dump(Brilliant(123, "four five six"), to: &output, maxDepth: 0)
expectEqual("â–¹ a.Brilliant #0\n", output)
}
do {
var output = ""
dump(Brilliant(123, "four five six"), to: &output, maxItems: 3)
let expected =
"â–¿ a.Brilliant #0\n" +
" - first: 123\n" +
" - second: \"four five six\"\n" +
" (1 more child)\n"
expectEqual(expected, output)
}
do {
var output = ""
dump(Brilliant(123, "four five six"), to: &output, maxItems: 2)
let expected =
"â–¿ a.Brilliant #0\n" +
" - first: 123\n" +
" (2 more children)\n"
expectEqual(expected, output)
}
do {
var output = ""
dump(Brilliant(123, "four five six"), to: &output, maxItems: 1)
let expected =
"â–¿ a.Brilliant #0\n" +
" (3 children)\n"
expectEqual(expected, output)
}
}
Reflection.test("ObjectIdentifier/Hashable,Comparable") {
// Check that object identifiers are unique to class instances.
let a = Brilliant(1, "")
let b = Brilliant(2, "")
let c = Brilliant(3, "")
checkHashable(
[a, b, c].map(ObjectIdentifier.init),
equalityOracle: { $0 == $1 })
// Comparable
func isComparable<X : Comparable>(_ x: X) {}
isComparable(ObjectIdentifier(a))
// Check the ObjectIdentifier created is stable
expectTrue(
(ObjectIdentifier(a) < ObjectIdentifier(b))
!= (ObjectIdentifier(a) > ObjectIdentifier(b)))
expectFalse(
ObjectIdentifier(a) >= ObjectIdentifier(b)
&& ObjectIdentifier(a) <= ObjectIdentifier(b))
// Check that ordering is transitive.
expectEqual(
[ ObjectIdentifier(a), ObjectIdentifier(b), ObjectIdentifier(c) ].sorted(),
[ ObjectIdentifier(c), ObjectIdentifier(b), ObjectIdentifier(a) ].sorted())
}
Reflection.test("ObjectIdentifier/CustomDebugStringConvertible") {
let obj1 = Brilliant(1, "")
let obj2 = Brilliant(2, "")
let oi1 = ObjectIdentifier(obj1)
let oi2 = ObjectIdentifier(obj2)
expectEqual(String(reflecting: oi1), String(reflecting: oi1))
expectNotEqual(String(reflecting: oi1), String(reflecting: oi2))
let p1 = UnsafeRawPointer(bitPattern: UInt(bitPattern: oi1))!
expectPrinted("ObjectIdentifier(\(p1))", oi1)
let p2 = UnsafeRawPointer(bitPattern: Int(bitPattern: oi1))!
expectPrinted("ObjectIdentifier(\(p2))", oi1)
}
Reflection.test("CustomMirrorIsInherited") {
do {
var output = ""
dump(Irradiant(), to: &output)
let expected =
"â–¿ a.Brilliant #0\n" +
" - first: 400\n" +
" - second: \"\"\n" +
" â–¿ self: a.Brilliant #0\n"
expectEqual(expected, output)
}
}
protocol SomeNativeProto {}
extension Int: SomeNativeProto {}
Reflection.test("MetatypeMirror") {
do {
var output = ""
let concreteMetatype = Int.self
dump(concreteMetatype, to: &output)
let expectedInt = "- Swift.Int #0\n"
expectEqual(expectedInt, output)
let anyMetatype: Any.Type = Int.self
output = ""
dump(anyMetatype, to: &output)
expectEqual(expectedInt, output)
let nativeProtocolMetatype: SomeNativeProto.Type = Int.self
output = ""
dump(nativeProtocolMetatype, to: &output)
expectEqual(expectedInt, output)
let concreteClassMetatype = SomeClass.self
let expectedSomeClass = "- a.SomeClass #0\n"
output = ""
dump(concreteClassMetatype, to: &output)
expectEqual(expectedSomeClass, output)
let nativeProtocolConcreteMetatype = SomeNativeProto.self
let expectedNativeProtocolConcrete = "- a.SomeNativeProto #0\n"
output = ""
dump(nativeProtocolConcreteMetatype, to: &output)
expectEqual(expectedNativeProtocolConcrete, output)
}
}
Reflection.test("TupleMirror") {
do {
var output = ""
let tuple =
(Brilliant(384, "seven six eight"), StructWithDefaultMirror("nine"))
dump(tuple, to: &output)
let expected =
"â–¿ (2 elements)\n" +
" â–¿ .0: a.Brilliant #0\n" +
" - first: 384\n" +
" - second: \"seven six eight\"\n" +
" â–¿ self: a.Brilliant #0\n" +
" â–¿ .1: a.StructWithDefaultMirror\n" +
" - s: \"nine\"\n"
expectEqual(expected, output)
expectEqual(.tuple, Mirror(reflecting: tuple).displayStyle)
}
do {
// A tuple of stdlib types with mirrors.
var output = ""
let tuple = (1, 2.5, false, "three")
dump(tuple, to: &output)
let expected =
"â–¿ (4 elements)\n" +
" - .0: 1\n" +
" - .1: 2.5\n" +
" - .2: false\n" +
" - .3: \"three\"\n"
expectEqual(expected, output)
}
do {
// A nested tuple.
var output = ""
let tuple = (1, ("Hello", "World"))
dump(tuple, to: &output)
let expected =
"â–¿ (2 elements)\n" +
" - .0: 1\n" +
" â–¿ .1: (2 elements)\n" +
" - .0: \"Hello\"\n" +
" - .1: \"World\"\n"
expectEqual(expected, output)
}
}
class DullClass {}
Reflection.test("ClassReflection") {
expectEqual(.`class`, Mirror(reflecting: DullClass()).displayStyle)
}
Reflection.test("String/Mirror") {
do {
var output = ""
dump("", to: &output)
let expected =
"- \"\"\n"
expectEqual(expected, output)
}
do {
// U+0061 LATIN SMALL LETTER A
// U+304B HIRAGANA LETTER KA
// U+3099 COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK
// U+1F425 FRONT-FACING BABY CHICK
var output = ""
dump("\u{61}\u{304b}\u{3099}\u{1f425}", to: &output)
let expected =
"- \"\u{61}\u{304b}\u{3099}\u{1f425}\"\n"
expectEqual(expected, output)
}
}
Reflection.test("String.UTF8View/Mirror") {
// U+0061 LATIN SMALL LETTER A
// U+304B HIRAGANA LETTER KA
// U+3099 COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK
var output = ""
dump("\u{61}\u{304b}\u{3099}".utf8, to: &output)
let expected =
"â–¿ UTF8View(\"\u{61}\u{304b}\u{3099}\")\n" +
" - 97\n" +
" - 227\n" +
" - 129\n" +
" - 139\n" +
" - 227\n" +
" - 130\n" +
" - 153\n"
expectEqual(expected, output)
}
Reflection.test("String.UTF16View/Mirror") {
// U+0061 LATIN SMALL LETTER A
// U+304B HIRAGANA LETTER KA
// U+3099 COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK
// U+1F425 FRONT-FACING BABY CHICK
var output = ""
dump("\u{61}\u{304b}\u{3099}\u{1f425}".utf16, to: &output)
let expected =
"â–¿ StringUTF16(\"\u{61}\u{304b}\u{3099}\u{1f425}\")\n" +
" - 97\n" +
" - 12363\n" +
" - 12441\n" +
" - 55357\n" +
" - 56357\n"
expectEqual(expected, output)
}
Reflection.test("String.UnicodeScalarView/Mirror") {
// U+0061 LATIN SMALL LETTER A
// U+304B HIRAGANA LETTER KA
// U+3099 COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK
// U+1F425 FRONT-FACING BABY CHICK
var output = ""
dump("\u{61}\u{304b}\u{3099}\u{1f425}".unicodeScalars, to: &output)
let expected =
"â–¿ StringUnicodeScalarView(\"\u{61}\u{304b}\u{3099}\u{1f425}\")\n" +
" - \"\u{61}\"\n" +
" - \"\\u{304B}\"\n" +
" - \"\\u{3099}\"\n" +
" - \"\\u{0001F425}\"\n"
expectEqual(expected, output)
}
Reflection.test("Character/Mirror") {
do {
// U+0061 LATIN SMALL LETTER A
let input: Character = "\u{61}"
var output = ""
dump(input, to: &output)
let expected =
"- \"\u{61}\"\n"
expectEqual(expected, output)
}
do {
// U+304B HIRAGANA LETTER KA
// U+3099 COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK
let input: Character = "\u{304b}\u{3099}"
var output = ""
dump(input, to: &output)
let expected =
"- \"\u{304b}\u{3099}\"\n"
expectEqual(expected, output)
}
do {
// U+1F425 FRONT-FACING BABY CHICK
let input: Character = "\u{1f425}"
var output = ""
dump(input, to: &output)
let expected =
"- \"\u{1f425}\"\n"
expectEqual(expected, output)
}
}
Reflection.test("UnicodeScalar") {
do {
// U+0061 LATIN SMALL LETTER A
let input: UnicodeScalar = "\u{61}"
var output = ""
dump(input, to: &output)
let expected =
"- \"\u{61}\"\n"
expectEqual(expected, output)
}
do {
// U+304B HIRAGANA LETTER KA
let input: UnicodeScalar = "\u{304b}"
var output = ""
dump(input, to: &output)
let expected =
"- \"\\u{304B}\"\n"
expectEqual(expected, output)
}
do {
// U+3099 COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK
let input: UnicodeScalar = "\u{3099}"
var output = ""
dump(input, to: &output)
let expected =
"- \"\\u{3099}\"\n"
expectEqual(expected, output)
}
do {
// U+1F425 FRONT-FACING BABY CHICK
let input: UnicodeScalar = "\u{1f425}"
var output = ""
dump(input, to: &output)
let expected =
"- \"\\u{0001F425}\"\n"
expectEqual(expected, output)
}
}
Reflection.test("Bool") {
do {
var output = ""
dump(false, to: &output)
let expected =
"- false\n"
expectEqual(expected, output)
}
do {
var output = ""
dump(true, to: &output)
let expected =
"- true\n"
expectEqual(expected, output)
}
}
// FIXME: these tests should cover Float80.
// FIXME: these tests should be automatically generated from the list of
// available floating point types.
Reflection.test("Float") {
do {
var output = ""
dump(Float.nan, to: &output)
let expected =
"- nan\n"
expectEqual(expected, output)
}
do {
var output = ""
dump(Float.infinity, to: &output)
let expected =
"- inf\n"
expectEqual(expected, output)
}
do {
var input: Float = 42.125
var output = ""
dump(input, to: &output)
let expected =
"- 42.125\n"
expectEqual(expected, output)
}
}
Reflection.test("Double") {
do {
var output = ""
dump(Double.nan, to: &output)
let expected =
"- nan\n"
expectEqual(expected, output)
}
do {
var output = ""
dump(Double.infinity, to: &output)
let expected =
"- inf\n"
expectEqual(expected, output)
}
do {
var input: Double = 42.125
var output = ""
dump(input, to: &output)
let expected =
"- 42.125\n"
expectEqual(expected, output)
}
}
// A struct type and class type whose NominalTypeDescriptor.FieldNames
// data is exactly eight bytes long. FieldNames data of exactly
// 4 or 8 or 16 bytes was once miscompiled on arm64.
struct EightByteFieldNamesStruct {
let abcdef = 42
}
class EightByteFieldNamesClass {
let abcdef = 42
}
Reflection.test("FieldNamesBug") {
do {
let expected =
"â–¿ a.EightByteFieldNamesStruct\n" +
" - abcdef: 42\n"
var output = ""
dump(EightByteFieldNamesStruct(), to: &output)
expectEqual(expected, output)
}
do {
let expected =
"â–¿ a.EightByteFieldNamesClass #0\n" +
" - abcdef: 42\n"
var output = ""
dump(EightByteFieldNamesClass(), to: &output)
expectEqual(expected, output)
}
}
Reflection.test("MirrorMirror") {
var object = 1
var mirror = Mirror(reflecting: object)
var mirrorMirror = Mirror(reflecting: mirror)
expectEqual(0, mirrorMirror.children.count)
}
Reflection.test("OpaquePointer/null") {
// Don't crash on null pointers. rdar://problem/19708338
let pointer: OpaquePointer? = nil
let mirror = Mirror(reflecting: pointer)
expectEqual(0, mirror.children.count)
}
Reflection.test("StaticString/Mirror") {
do {
var output = ""
dump("" as StaticString, to: &output)
let expected =
"- \"\"\n"
expectEqual(expected, output)
}
do {
// U+0061 LATIN SMALL LETTER A
// U+304B HIRAGANA LETTER KA
// U+3099 COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK
// U+1F425 FRONT-FACING BABY CHICK
var output = ""
dump("\u{61}\u{304b}\u{3099}\u{1f425}" as StaticString, to: &output)
let expected =
"- \"\u{61}\u{304b}\u{3099}\u{1f425}\"\n"
expectEqual(expected, output)
}
}
Reflection.test("DictionaryIterator/Mirror") {
let d: [MinimalHashableValue : OpaqueValue<Int>] =
[ MinimalHashableValue(0) : OpaqueValue(0) ]
var output = ""
dump(d.makeIterator(), to: &output)
let expected =
"- Swift.DictionaryIterator<StdlibUnittest.MinimalHashableValue, StdlibUnittest.OpaqueValue<Swift.Int>>\n"
expectEqual(expected, output)
}
Reflection.test("SetIterator/Mirror") {
let s: Set<MinimalHashableValue> = [ MinimalHashableValue(0)]
var output = ""
dump(s.makeIterator(), to: &output)
let expected =
"- Swift.SetIterator<StdlibUnittest.MinimalHashableValue>\n"
expectEqual(expected, output)
}
var BitTwiddlingTestSuite = TestSuite("BitTwiddling")
BitTwiddlingTestSuite.test("_pointerSize") {
#if arch(i386) || arch(arm)
expectEqual(4, MemoryLayout<Optional<AnyObject>>.size)
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le)
expectEqual(8, MemoryLayout<Optional<AnyObject>>.size)
#else
fatalError("implement")
#endif
}
BitTwiddlingTestSuite.test("_isPowerOf2/Int") {
func asInt(_ a: Int) -> Int { return a }
expectFalse(_isPowerOf2(asInt(-1025)))
expectFalse(_isPowerOf2(asInt(-1024)))
expectFalse(_isPowerOf2(asInt(-1023)))
expectFalse(_isPowerOf2(asInt(-4)))
expectFalse(_isPowerOf2(asInt(-3)))
expectFalse(_isPowerOf2(asInt(-2)))
expectFalse(_isPowerOf2(asInt(-1)))
expectFalse(_isPowerOf2(asInt(0)))
expectTrue(_isPowerOf2(asInt(1)))
expectTrue(_isPowerOf2(asInt(2)))
expectFalse(_isPowerOf2(asInt(3)))
expectTrue(_isPowerOf2(asInt(1024)))
#if arch(i386) || arch(arm)
// Not applicable to 32-bit architectures.
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
expectTrue(_isPowerOf2(asInt(0x8000_0000)))
#else
fatalError("implement")
#endif
expectFalse(_isPowerOf2(Int.min))
expectFalse(_isPowerOf2(Int.max))
}
BitTwiddlingTestSuite.test("_isPowerOf2/UInt") {
func asUInt(_ a: UInt) -> UInt { return a }
expectFalse(_isPowerOf2(asUInt(0)))
expectTrue(_isPowerOf2(asUInt(1)))
expectTrue(_isPowerOf2(asUInt(2)))
expectFalse(_isPowerOf2(asUInt(3)))
expectTrue(_isPowerOf2(asUInt(1024)))
expectTrue(_isPowerOf2(asUInt(0x8000_0000)))
expectFalse(_isPowerOf2(UInt.max))
}
var AvailabilityVersionsTestSuite = TestSuite("AvailabilityVersions")
AvailabilityVersionsTestSuite.test("lexicographic_compare") {
func version(
_ major: Int,
_ minor: Int,
_ patch: Int
) -> _SwiftNSOperatingSystemVersion {
return _SwiftNSOperatingSystemVersion(
majorVersion: major,
minorVersion: minor,
patchVersion: patch
)
}
checkComparable(.eq, version(0, 0, 0), version(0, 0, 0))
checkComparable(.lt, version(0, 0, 0), version(0, 0, 1))
checkComparable(.lt, version(0, 0, 0), version(0, 1, 0))
checkComparable(.lt, version(0, 0, 0), version(1, 0, 0))
checkComparable(.lt, version(10, 9, 0), version(10, 10, 0))
checkComparable(.lt, version(10, 9, 11), version(10, 10, 0))
checkComparable(.lt, version(10, 10, 3), version(10, 11, 0))
checkComparable(.lt, version(8, 3, 0), version(9, 0, 0))
checkComparable(.lt, version(0, 11, 0), version(10, 10, 4))
checkComparable(.lt, version(0, 10, 0), version(10, 10, 4))
checkComparable(.lt, version(3, 2, 1), version(4, 3, 2))
checkComparable(.lt, version(1, 2, 3), version(2, 3, 1))
checkComparable(.eq, version(10, 11, 12), version(10, 11, 12))
checkEquatable(true, version(1, 2, 3), version(1, 2, 3))
checkEquatable(false, version(1, 2, 3), version(1, 2, 42))
checkEquatable(false, version(1, 2, 3), version(1, 42, 3))
checkEquatable(false, version(1, 2, 3), version(42, 2, 3))
}
AvailabilityVersionsTestSuite.test("_stdlib_isOSVersionAtLeast") {
func isAtLeastOS(_ major: Int, _ minor: Int, _ patch: Int) -> Bool {
return _getBool(_stdlib_isOSVersionAtLeast(major._builtinWordValue,
minor._builtinWordValue,
patch._builtinWordValue))
}
// _stdlib_isOSVersionAtLeast is broken for
// watchOS. rdar://problem/20234735
#if os(OSX) || os(iOS) || os(tvOS) || os(watchOS)
// This test assumes that no version component on an OS we test upon
// will ever be greater than 1066 and that every major version will always
// be greater than 1.
expectFalse(isAtLeastOS(1066, 0, 0))
expectTrue(isAtLeastOS(0, 1066, 0))
expectTrue(isAtLeastOS(0, 0, 1066))
#endif
}
runAllTests()