//===--- Mirror.swift -----------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // RUN: rm -rf %t // RUN: mkdir -p %t // // RUN: if [ %target-runtime == "objc" ]; \ // RUN: then \ // RUN: %target-clang %S/Inputs/Mirror/Mirror.mm -c -o %t/Mirror.mm.o -g && \ // RUN: %target-build-swift %s -I %S/Inputs/Mirror/ -Xlinker %t/Mirror.mm.o -o %t/Mirror; \ // RUN: else \ // RUN: %target-build-swift %s -o %t/Mirror; \ // RUN: fi // RUN: %target-run %t/Mirror // REQUIRES: executable_test import StdlibUnittest var mirrors = TestSuite("Mirrors") extension Mirror { public var testDescription: String { let nil_ = "nil" return "[" + children.lazy .map { "\($0.0 ?? nil_): \(String(reflecting: $0.1))" } .joined(separator: ", ") + "]" } } mirrors.test("RandomAccessStructure") { struct Eggs : CustomReflectable { var customMirror: Mirror { return Mirror(self, unlabeledChildren: ["aay", "bee", "cee"]) } } let x = Eggs().customMirror expectEqual("[nil: \"aay\", nil: \"bee\", nil: \"cee\"]", x.testDescription) } let letters = "abcdefghijklmnopqrstuvwxyz " func find(_ substring: String, within domain: String) -> String.Index? { let domainCount = domain.characters.count let substringCount = substring.characters.count if (domainCount < substringCount) { return nil } var sliceStart = domain.startIndex var sliceEnd = domain.index(sliceStart, offsetBy: substringCount) var i = 0 while true { if domain[sliceStart..") { class C : CustomReflectable { var c: UInt = 3 var customMirror: Mirror { return Mirror(self, children: ["sea": c + 1]) } } let c = Mirror(reflecting: C()) expectTrue(c.subjectType == C.self) expectNil(c.superclassMirror) expectEqual(1, c.children.count) expectEqual("sea", c.children.first!.label) expectEqual(4, c.children.first!.value as? UInt) } mirrors.test("class/Plain/Plain") { class A { var a: Int = 1 } class B : A { var b: UInt = 42 } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) if let bChild = expectNotNil(b.children.first) { expectEqual("b", bChild.label) expectEqual(42, bChild.value as? UInt) } if let a = expectNotNil(b.superclassMirror) { expectTrue(a.subjectType == A.self) if let aChild = expectNotNil(a.children.first) { expectEqual("a", aChild.label) expectEqual(1, aChild.value as? Int) expectNil(a.superclassMirror) } } } mirrors.test("class/UncustomizedSuper/Synthesized/Implicit") { class A { var a: Int = 1 } class B : A, CustomReflectable { var b: UInt = 42 var customMirror: Mirror { return Mirror(self, children: ["bee": b]) } } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) if let a = expectNotNil(b.superclassMirror) { expectTrue(a.subjectType == A.self) expectEqual("a", a.children.first?.label) expectNil(a.superclassMirror) } } mirrors.test("class/UncustomizedSuper/Synthesized/Explicit") { class A { var a: Int = 1 } class B : A, CustomReflectable { var b: UInt = 42 var customMirror: Mirror { return Mirror( self, children: ["bee": b], ancestorRepresentation: .generated) } } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) if let a = expectNotNil(b.superclassMirror) { expectTrue(a.subjectType == A.self) expectEqual("a", a.children.first!.label) expectNil(a.superclassMirror) } } mirrors.test("class/CustomizedSuper/Synthesized") { class A : CustomReflectable { var a: Int = 1 var customMirror: Mirror { return Mirror(self, children: ["aye": a]) } } class B : A { var b: UInt = 42 // This is an unusual case: when writing override on a // customMirror implementation you would typically want to pass // ancestorRepresentation: .customized(super.customMirror) or, in // rare cases, ancestorRepresentation: .Suppressed. However, it // has an expected behavior, which we test here. override var customMirror: Mirror { return Mirror(self, children: ["bee": b]) } } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) if let a = expectNotNil(b.superclassMirror) { expectTrue(a.subjectType == A.self) expectEqual("a", a.children.first!.label) expectNil(a.superclassMirror) } } #if _runtime(_ObjC) import Foundation //===--- ObjC Base Classes ------------------------------------------------===// mirrors.test("class/ObjCPlain/Plain") { class A : NSObject { var a: Int = 1 } class B : A { var b: UInt = 42 } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) if let bChild = expectNotNil(b.children.first) { expectEqual("b", bChild.label) expectEqual(42, bChild.value as? UInt) } if let a = expectNotNil(b.superclassMirror) { expectTrue(a.subjectType == A.self) if let aChild = expectNotNil(a.children.first) { expectEqual("a", aChild.label) expectEqual(1, aChild.value as? Int) if let o = expectNotNil(a.superclassMirror) { expectEqual("NSObject", String(reflecting: o.subjectType)) } } } } mirrors.test("class/ObjCUncustomizedSuper/Synthesized/Implicit") { class A : NSObject { var a: Int = 1 } class B : A, CustomReflectable { var b: UInt = 42 var customMirror: Mirror { return Mirror(self, children: ["bee": b]) } } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) if let a = expectNotNil(b.superclassMirror) { expectTrue(a.subjectType == A.self) expectEqual("a", a.children.first?.label) if let o = expectNotNil(a.superclassMirror) { expectTrue(o.subjectType == NSObject.self) } } } mirrors.test("class/ObjCUncustomizedSuper/Synthesized/Explicit") { class A : NSObject { var a: Int = 1 } class B : A, CustomReflectable { var b: UInt = 42 var customMirror: Mirror { return Mirror( self, children: ["bee": b], ancestorRepresentation: .generated) } } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) if let a = expectNotNil(b.superclassMirror) { expectTrue(a.subjectType == A.self) expectEqual("a", a.children.first!.label) if let o = expectNotNil(a.superclassMirror) { expectTrue(o.subjectType == NSObject.self) } } } mirrors.test("class/ObjCCustomizedSuper/Synthesized") { class A : DateFormatter, CustomReflectable { var a: Int = 1 var customMirror: Mirror { return Mirror(self, children: ["aye": a]) } } class B : A { var b: UInt = 42 // This is an unusual case: when writing override on a // customMirror implementation you would typically want to pass // ancestorRepresentation: .customized(super.customMirror) or, in // rare cases, ancestorRepresentation: .Suppressed. However, it // has an expected behavior, which we test here. override var customMirror: Mirror { return Mirror(self, children: ["bee": b]) } } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) if let a = expectNotNil(b.superclassMirror) { expectTrue(a.subjectType == A.self) expectEqual("a", a.children.first!.label) if let d = expectNotNil(a.superclassMirror) { expectTrue(d.subjectType == DateFormatter.self) if let f = expectNotNil(d.superclassMirror) { expectTrue(f.subjectType == Formatter.self) if let o = expectNotNil(f.superclassMirror) { expectTrue(o.subjectType == NSObject.self) expectNil(o.superclassMirror) } } } } } #endif // _runtime(_ObjC) //===--- Suppressed Superclass Mirrors ------------------------------------===// mirrors.test("Class/Root/NoSuperclassMirror") { class B : CustomReflectable { var b: String = "two" var customMirror: Mirror { return Mirror( self, children: ["bee": b], ancestorRepresentation: .suppressed) } } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) expectNil(b.superclassMirror) expectEqual(1, b.children.count) expectEqual("bee", b.children.first!.label) } mirrors.test("class/UncustomizedSuper/NoSuperclassMirror") { class A { var a: Int = 1 } class B : A, CustomReflectable { var b: UInt = 42 var customMirror: Mirror { return Mirror( self, children: ["bee": b], ancestorRepresentation: .suppressed) } } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) expectNil(b.superclassMirror) } mirrors.test("class/CustomizedSuper/NoSuperclassMirror") { class A : CustomReflectable { var a: Int = 1 var customMirror: Mirror { return Mirror(self, children: ["aye": a]) } } class B : A { var b: UInt = 42 override var customMirror: Mirror { return Mirror( self, children: ["bee": b], ancestorRepresentation: .suppressed) } } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) expectNil(b.superclassMirror) } //===--- Override Superclass Mirrors --------------------------------------===// mirrors.test("class/CustomizedSuper/SuperclassCustomMirror/Direct") { class A : CustomReflectable { var a: Int = 1 var customMirror: Mirror { return Mirror(self, children: ["aye": a]) } } // B inherits A directly class B : A { var b: UInt = 42 override var customMirror: Mirror { return Mirror( self, children: ["bee": b], ancestorRepresentation: .customized({ super.customMirror })) } } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) if let a = expectNotNil(b.superclassMirror) { expectTrue(a.subjectType == A.self) expectEqual("aye", a.children.first!.label) expectNil(a.superclassMirror) } } mirrors.test("class/CustomizedSuper/SuperclassCustomMirror/Indirect") { class A : CustomReflectable { var a: Int = 1 var customMirror: Mirror { return Mirror(self, children: ["aye": a]) } } class X : A {} class Y : X {} // B inherits A indirectly through X and Y class B : Y { var b: UInt = 42 override var customMirror: Mirror { return Mirror( self, children: ["bee": b], ancestorRepresentation: .customized({ super.customMirror })) } } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) if let y = expectNotNil(b.superclassMirror) { expectTrue(y.subjectType == Y.self) if let x = expectNotNil(y.superclassMirror) { expectTrue(x.subjectType == X.self) expectEqual(0, x.children.count) if let a = expectNotNil(x.superclassMirror) { expectTrue(a.subjectType == A.self) if let aye = expectNotNil(a.children.first) { expectEqual("aye", aye.label) } } } } } mirrors.test("class/CustomizedSuper/SuperclassCustomMirror/Indirect2") { class A : CustomLeafReflectable { var a: Int = 1 var customMirror: Mirror { return Mirror( self, children: ["aye": a]) } } class X : A {} class Y : X {} // B inherits A indirectly through X and Y class B : Y { var b: UInt = 42 override var customMirror: Mirror { return Mirror( self, children: ["bee": b], ancestorRepresentation: .customized({ super.customMirror })) } } let b = Mirror(reflecting: B()) expectTrue(b.subjectType == B.self) if let a = expectNotNil(b.superclassMirror) { expectTrue(a.subjectType == A.self) if let aye = expectNotNil(a.children.first) { expectEqual("aye", aye.label) } } } mirrors.test("class/Cluster") { class A : CustomLeafReflectable { var a: Int = 1 var customMirror: Mirror { return Mirror( self, children: ["aye": a]) } } class X : A {} class Y : X {} let a = Mirror(reflecting: Y()) expectTrue(a.subjectType == A.self) if let aye = expectNotNil(a.children.first) { expectEqual("aye", aye.label) } } //===--- End Class Support ------------------------------------------------===// //===----------------------------------------------------------------------===// mirrors.test("Addressing") { let m0 = Mirror(reflecting: [1, 2, 3]) expectEqual(1, m0.descendant(0) as? Int) expectEqual(2, m0.descendant(1) as? Int) expectEqual(3, m0.descendant(2) as? Int) let m1 = Mirror(reflecting: (a: ["one", "two", "three"], 4)) let ott0 = m1.descendant(0) as? [String] expectNotNil(ott0) let ott1 = m1.descendant("a") as? [String] expectNotNil(ott1) if ott0 != nil && ott1 != nil { expectEqualSequence(ott0!, ott1!) } expectEqual(4, m1.descendant(1) as? Int) expectEqual(4, m1.descendant(".1") as? Int) expectEqual("one", m1.descendant(0, 0) as? String) expectEqual("two", m1.descendant(0, 1) as? String) expectEqual("three", m1.descendant(0, 2) as? String) expectEqual("one", m1.descendant("a", 0) as? String) struct Zee : CustomReflectable { var customMirror: Mirror { return Mirror(self, children: ["bark": 1, "bite": 0]) } } let x = [ (a: ["one", "two", "three"], b: Zee()), (a: ["five"], b: Zee()), (a: [], b: Zee())] let m = Mirror(reflecting: x) let two = m.descendant(0, "a", 1) expectEqual("two", two as? String) expectEqual(1, m.descendant(1, 1, "bark") as? Int) expectEqual(0, m.descendant(1, 1, "bite") as? Int) expectNil(m.descendant(1, 1, "bork")) } mirrors.test("Invalid Path Type") .skip(.custom( { _isFastAssertConfiguration() }, reason: "this trap is not guaranteed to happen in -Ounchecked")) .code { struct X : MirrorPath {} let m = Mirror(reflecting: [1, 2, 3]) expectEqual(1, m.descendant(0) as? Int) expectCrashLater() _ = m.descendant(X()) } mirrors.test("PlaygroundQuickLook") { // Customization works. struct CustomQuickie : CustomPlaygroundQuickLookable { var customPlaygroundQuickLook: PlaygroundQuickLook { return .point(1.25, 42) } } switch PlaygroundQuickLook(reflecting: CustomQuickie()) { case .point(1.25, 42): break default: expectTrue(false) } // PlaygroundQuickLook support from Legacy Mirrors works. switch PlaygroundQuickLook(reflecting: true) { case .bool(true): break default: expectTrue(false) } // With no Legacy Mirror QuickLook support, we fall back to // String(reflecting: ). struct X {} switch PlaygroundQuickLook(reflecting: X()) { case .text(let text): #if _runtime(_ObjC) // FIXME: Enable if non-objc hasSuffix is implemented. expectTrue(text.contains("X #1 in"), text) #endif default: expectTrue(false) } struct Y : CustomDebugStringConvertible { var debugDescription: String { return "Why?" } } switch PlaygroundQuickLook(reflecting: Y()) { case .text("Why?"): break default: expectTrue(false) } } class Parent {} extension Parent : _DefaultCustomPlaygroundQuickLookable { var _defaultCustomPlaygroundQuickLook: PlaygroundQuickLook { return .text("base") } } class Child : Parent { } class FancyChild : Parent, CustomPlaygroundQuickLookable { var customPlaygroundQuickLook: PlaygroundQuickLook { return .text("child") } } mirrors.test("_DefaultCustomPlaygroundQuickLookable") { // testing the workaround for custom quicklookables in subclasses switch PlaygroundQuickLook(reflecting: Child()) { case .text("base"): break default: expectUnreachable("Base custom quicklookable was expected") } switch PlaygroundQuickLook(reflecting: FancyChild()) { case .text("child"): break default: expectUnreachable("FancyChild custom quicklookable was expected") } } #if _runtime(_ObjC) import MirrorObjC mirrors.test("ObjC") { // Some Foundation classes lie about their ivars, which would crash // a mirror; make sure we are not automatically exposing ivars of // Objective-C classes from the default mirror implementation. expectEqual(0, Mirror(reflecting: HasIVars()).children.count) } #endif mirrors.test("String.init") { expectEqual("42", String(42)) expectEqual("42", String("42")) expectEqual("42", String(reflecting: 42)) expectEqual("\"42\"", String(reflecting: "42")) } runAllTests()