mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[test] renaming test/1_stdlib to just test/stdlib
This commit is contained in:
786
test/stdlib/Mirror.swift
Normal file
786
test/stdlib/Mirror.swift
Normal file
@@ -0,0 +1,786 @@
|
||||
//===--- Mirror.swift -----------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See http://swift.org/LICENSE.txt for license information
|
||||
// See http://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..<sliceEnd] == substring {
|
||||
return sliceStart
|
||||
}
|
||||
if i == domainCount - substringCount { break }
|
||||
sliceStart = domain.index(after: sliceStart)
|
||||
sliceEnd = domain.index(after: sliceEnd)
|
||||
i += 1
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
mirrors.test("ForwardStructure") {
|
||||
struct DoubleYou : CustomReflectable {
|
||||
var customMirror: Mirror {
|
||||
return Mirror(
|
||||
self,
|
||||
unlabeledChildren: Set(letters.characters),
|
||||
displayStyle: .`set`)
|
||||
}
|
||||
}
|
||||
|
||||
let w = DoubleYou().customMirror
|
||||
expectEqual(.`set`, w.displayStyle)
|
||||
expectEqual(letters.characters.count, numericCast(w.children.count))
|
||||
|
||||
// Because we don't control the order of a Set, we need to do a
|
||||
// fancy dance in order to validate the result.
|
||||
let description = w.testDescription
|
||||
for c in letters.characters {
|
||||
let expected = "nil: \"\(c)\""
|
||||
expectNotEmpty(find(expected, within: description))
|
||||
}
|
||||
}
|
||||
|
||||
mirrors.test("BidirectionalStructure") {
|
||||
struct Why : CustomReflectable {
|
||||
var customMirror: Mirror {
|
||||
return Mirror(
|
||||
self,
|
||||
unlabeledChildren: letters.characters,
|
||||
displayStyle: .collection)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that the basics seem to work
|
||||
let y = Why().customMirror
|
||||
expectEqual(.`collection`, y.displayStyle)
|
||||
|
||||
let description = y.testDescription
|
||||
expectEqual(
|
||||
"[nil: \"a\", nil: \"b\", nil: \"c\", nil: \"",
|
||||
description[description.startIndex..<description.characters.index(of: "d")!])
|
||||
}
|
||||
|
||||
mirrors.test("LabeledStructure") {
|
||||
struct Zee : CustomReflectable, CustomStringConvertible {
|
||||
var customMirror: Mirror {
|
||||
return Mirror(self, children: ["bark": 1, "bite": 0])
|
||||
}
|
||||
var description: String { return "Zee" }
|
||||
}
|
||||
|
||||
let z = Zee().customMirror
|
||||
expectEqual("[bark: 1, bite: 0]", z.testDescription)
|
||||
expectEmpty(z.displayStyle)
|
||||
|
||||
struct Zee2 : CustomReflectable {
|
||||
var customMirror: Mirror {
|
||||
return Mirror(
|
||||
self, children: ["bark": 1, "bite": 0], displayStyle: .dictionary)
|
||||
}
|
||||
}
|
||||
let z2 = Zee2().customMirror
|
||||
expectEqual(.dictionary, z2.displayStyle)
|
||||
expectEqual("[bark: 1, bite: 0]", z2.testDescription)
|
||||
|
||||
struct Heterogeny : CustomReflectable {
|
||||
var customMirror: Mirror {
|
||||
return Mirror(
|
||||
self, children: ["bark": 1, "bite": Zee()])
|
||||
}
|
||||
}
|
||||
let h = Heterogeny().customMirror
|
||||
expectEqual("[bark: 1, bite: Zee]", h.testDescription)
|
||||
}
|
||||
|
||||
mirrors.test("Legacy") {
|
||||
let m = Mirror(reflecting: [1, 2, 3])
|
||||
expectTrue(m.subjectType == [Int].self)
|
||||
|
||||
let x0: [Mirror.Child] = [
|
||||
(label: nil, value: 1),
|
||||
(label: nil, value: 2),
|
||||
(label: nil, value: 3)
|
||||
]
|
||||
expectFalse(
|
||||
zip(x0, m.children).contains {
|
||||
$0.0.value as! Int != $0.1.value as! Int
|
||||
})
|
||||
|
||||
class B { let bx: Int = 0 }
|
||||
class D : B { let dx: Int = 1 }
|
||||
|
||||
let mb = Mirror(reflecting: B())
|
||||
|
||||
func expectBMirror(
|
||||
_ mb: Mirror, stackTrace: SourceLocStack = SourceLocStack(),
|
||||
file: String = #file, line: UInt = #line
|
||||
) {
|
||||
expectTrue(mb.subjectType == B.self,
|
||||
stackTrace: stackTrace, file: file, line: line)
|
||||
|
||||
expectEmpty(
|
||||
mb.superclassMirror,
|
||||
stackTrace: stackTrace, file: file, line: line)
|
||||
|
||||
expectEqual(
|
||||
1, mb.children.count,
|
||||
stackTrace: stackTrace, file: file, line: line)
|
||||
|
||||
expectEqual(
|
||||
"bx", mb.children.first?.label,
|
||||
stackTrace: stackTrace, file: file, line: line)
|
||||
|
||||
expectEqual(
|
||||
0, mb.children.first?.value as? Int,
|
||||
stackTrace: stackTrace, file: file, line: line)
|
||||
}
|
||||
|
||||
expectBMirror(mb)
|
||||
|
||||
// Ensure that the base class instance is properly filtered out of
|
||||
// the child list
|
||||
do {
|
||||
let md = Mirror(reflecting: D())
|
||||
expectTrue(md.subjectType == D.self)
|
||||
|
||||
expectEqual(1, md.children.count)
|
||||
expectEqual("dx", md.children.first?.label)
|
||||
expectEqual(1, md.children.first?.value as? Int)
|
||||
|
||||
expectNotEmpty(md.superclassMirror)
|
||||
if let mb2 = md.superclassMirror { expectBMirror(mb2) }
|
||||
}
|
||||
|
||||
do {
|
||||
// Ensure that we reflect on the dynamic type of the subject
|
||||
let md = Mirror(reflecting: D() as B)
|
||||
expectTrue(md.subjectType == D.self)
|
||||
|
||||
expectEqual(1, md.children.count)
|
||||
expectEqual("dx", md.children.first?.label)
|
||||
expectEqual(1, md.children.first?.value as? Int)
|
||||
|
||||
expectNotEmpty(md.superclassMirror)
|
||||
if let mb2 = md.superclassMirror { expectBMirror(mb2) }
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//===--- Class Support ----------------------------------------------------===//
|
||||
|
||||
mirrors.test("Class/Root/Uncustomized") {
|
||||
class A { var a: Int = 1 }
|
||||
|
||||
let a = Mirror(reflecting: A())
|
||||
expectTrue(a.subjectType == A.self)
|
||||
expectEmpty(a.superclassMirror)
|
||||
expectEqual(1, a.children.count)
|
||||
expectEqual("a", a.children.first!.label)
|
||||
}
|
||||
|
||||
//===--- Generated Superclass Mirrors -------------------------------------===//
|
||||
mirrors.test("Class/Root/superclass:.generated") {
|
||||
class B : CustomReflectable {
|
||||
var b: String = "two"
|
||||
var customMirror: Mirror {
|
||||
return Mirror(
|
||||
self, children: ["bee": b], ancestorRepresentation: .generated)
|
||||
}
|
||||
}
|
||||
|
||||
let b = Mirror(reflecting: B())
|
||||
expectTrue(b.subjectType == B.self)
|
||||
expectEmpty(b.superclassMirror)
|
||||
expectEqual(1, b.children.count)
|
||||
expectEqual("bee", b.children.first!.label)
|
||||
expectEqual("two", b.children.first!.value as? String)
|
||||
}
|
||||
|
||||
|
||||
mirrors.test("class/Root/superclass:<default>") {
|
||||
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)
|
||||
expectEmpty(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 = expectNotEmpty(b.children.first) {
|
||||
expectEqual("b", bChild.label)
|
||||
expectEqual(42, bChild.value as? UInt)
|
||||
}
|
||||
if let a = expectNotEmpty(b.superclassMirror) {
|
||||
expectTrue(a.subjectType == A.self)
|
||||
if let aChild = expectNotEmpty(a.children.first) {
|
||||
expectEqual("a", aChild.label)
|
||||
expectEqual(1, aChild.value as? Int)
|
||||
expectEmpty(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 = expectNotEmpty(b.superclassMirror) {
|
||||
expectTrue(a.subjectType == A.self)
|
||||
expectEqual("a", a.children.first?.label)
|
||||
expectEmpty(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 = expectNotEmpty(b.superclassMirror) {
|
||||
expectTrue(a.subjectType == A.self)
|
||||
expectEqual("a", a.children.first!.label)
|
||||
expectEmpty(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 = expectNotEmpty(b.superclassMirror) {
|
||||
expectTrue(a.subjectType == A.self)
|
||||
expectEqual("a", a.children.first!.label)
|
||||
expectEmpty(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 = expectNotEmpty(b.children.first) {
|
||||
expectEqual("b", bChild.label)
|
||||
expectEqual(42, bChild.value as? UInt)
|
||||
}
|
||||
if let a = expectNotEmpty(b.superclassMirror) {
|
||||
expectTrue(a.subjectType == A.self)
|
||||
if let aChild = expectNotEmpty(a.children.first) {
|
||||
expectEqual("a", aChild.label)
|
||||
expectEqual(1, aChild.value as? Int)
|
||||
if let o = expectNotEmpty(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 = expectNotEmpty(b.superclassMirror) {
|
||||
expectTrue(a.subjectType == A.self)
|
||||
expectEqual("a", a.children.first?.label)
|
||||
if let o = expectNotEmpty(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 = expectNotEmpty(b.superclassMirror) {
|
||||
expectTrue(a.subjectType == A.self)
|
||||
expectEqual("a", a.children.first!.label)
|
||||
if let o = expectNotEmpty(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 = expectNotEmpty(b.superclassMirror) {
|
||||
expectTrue(a.subjectType == A.self)
|
||||
expectEqual("a", a.children.first!.label)
|
||||
if let d = expectNotEmpty(a.superclassMirror) {
|
||||
expectTrue(d.subjectType == DateFormatter.self)
|
||||
if let f = expectNotEmpty(d.superclassMirror) {
|
||||
expectTrue(f.subjectType == Formatter.self)
|
||||
if let o = expectNotEmpty(f.superclassMirror) {
|
||||
expectTrue(o.subjectType == NSObject.self)
|
||||
expectEmpty(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)
|
||||
expectEmpty(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)
|
||||
expectEmpty(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)
|
||||
expectEmpty(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 = expectNotEmpty(b.superclassMirror) {
|
||||
expectTrue(a.subjectType == A.self)
|
||||
expectEqual("aye", a.children.first!.label)
|
||||
expectEmpty(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 = expectNotEmpty(b.superclassMirror) {
|
||||
expectTrue(y.subjectType == Y.self)
|
||||
if let x = expectNotEmpty(y.superclassMirror) {
|
||||
expectTrue(x.subjectType == X.self)
|
||||
expectEqual(0, x.children.count)
|
||||
if let a = expectNotEmpty(x.superclassMirror) {
|
||||
expectTrue(a.subjectType == A.self)
|
||||
if let aye = expectNotEmpty(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 = expectNotEmpty(b.superclassMirror) {
|
||||
expectTrue(a.subjectType == A.self)
|
||||
if let aye = expectNotEmpty(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 = expectNotEmpty(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"], b: 4))
|
||||
let ott0 = m1.descendant(0) as? [String]
|
||||
expectNotEmpty(ott0)
|
||||
let ott1 = m1.descendant(".0") as? [String]
|
||||
expectNotEmpty(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(".0", 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, ".0", 1)
|
||||
expectEqual("two", two as? String)
|
||||
expectEqual(1, m.descendant(1, 1, "bark") as? Int)
|
||||
expectEqual(0, m.descendant(1, 1, "bite") as? Int)
|
||||
expectEmpty(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.hasSuffix(".(X #1)()"), 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()
|
||||
Reference in New Issue
Block a user