Skip to content

Commit 92b7e16

Browse files
committed
[PlaygroundLogger] Implemented support for the CustomPlaygroundDisplayConvertible protocol.
Implementations of `CustomPlaygroundDisplayConvertible` are now checked; the instance returned by `playgroundDescription` is sent back through the primary initializer. This includes a super-basic test that this functionality works.
1 parent 6958a83 commit 92b7e16

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

PlaygroundLogger/PlaygroundLogger.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@
8181
5E5FE50B202D13C800E28C3C /* PGLConcurrentMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E5FE50A202D13C800E28C3C /* PGLConcurrentMap.swift */; };
8282
5ECE8F911FFCD2A70034D9BC /* LegacyPlaygroundLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ECE8F901FFCD2A70034D9BC /* LegacyPlaygroundLoggerTests.swift */; };
8383
5EE3867420352F3200D625F0 /* CGFloat+CustomOpaqueLoggable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EE3867320352F3200D625F0 /* CGFloat+CustomOpaqueLoggable.swift */; };
84+
5EF581532041387C00AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EF581512041384700AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift */; };
85+
5EF581542041387C00AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EF581512041384700AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift */; };
86+
5EF581552041387C00AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EF581512041384700AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift */; };
8487
5EFE9193203F6CF900E21BAA /* LegacyPlaygroundLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ECE8F901FFCD2A70034D9BC /* LegacyPlaygroundLoggerTests.swift */; };
8588
5EFE919B203F6DD700E21BAA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EFE919A203F6DD700E21BAA /* AppDelegate.swift */; };
8689
5EFE919D203F6DD700E21BAA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EFE919C203F6DD700E21BAA /* ViewController.swift */; };
@@ -247,6 +250,7 @@
247250
5E5FE50A202D13C800E28C3C /* PGLConcurrentMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PGLConcurrentMap.swift; sourceTree = "<group>"; };
248251
5ECE8F901FFCD2A70034D9BC /* LegacyPlaygroundLoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyPlaygroundLoggerTests.swift; sourceTree = "<group>"; };
249252
5EE3867320352F3200D625F0 /* CGFloat+CustomOpaqueLoggable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGFloat+CustomOpaqueLoggable.swift"; sourceTree = "<group>"; };
253+
5EF581512041384700AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPlaygroundDisplayConvertibleTests.swift; sourceTree = "<group>"; };
250254
5EFE9189203F6CC400E21BAA /* PlaygroundLoggerTests_iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PlaygroundLoggerTests_iOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
251255
5EFE918D203F6CC400E21BAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
252256
5EFE9198203F6DD700E21BAA /* PlaygroundLoggerTestHost_iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PlaygroundLoggerTestHost_iOS.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -366,6 +370,7 @@
366370
5E2646341FB64876002DC6B6 /* PlaygroundLoggerTests */ = {
367371
isa = PBXGroup;
368372
children = (
373+
5EF581512041384700AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift */,
369374
5E5D777F2040BD7D00EBC3A9 /* LogPolicyTests.swift */,
370375
5ECE8F901FFCD2A70034D9BC /* LegacyPlaygroundLoggerTests.swift */,
371376
);
@@ -927,6 +932,7 @@
927932
buildActionMask = 2147483647;
928933
files = (
929934
5E5D77802040BD7D00EBC3A9 /* LogPolicyTests.swift in Sources */,
935+
5EF581532041387C00AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift in Sources */,
930936
5ECE8F911FFCD2A70034D9BC /* LegacyPlaygroundLoggerTests.swift in Sources */,
931937
);
932938
runOnlyForDeploymentPostprocessing = 0;
@@ -936,6 +942,7 @@
936942
buildActionMask = 2147483647;
937943
files = (
938944
5E5D77812040BD7D00EBC3A9 /* LogPolicyTests.swift in Sources */,
945+
5EF581542041387C00AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift in Sources */,
939946
5EFE9193203F6CF900E21BAA /* LegacyPlaygroundLoggerTests.swift in Sources */,
940947
);
941948
runOnlyForDeploymentPostprocessing = 0;
@@ -963,6 +970,7 @@
963970
buildActionMask = 2147483647;
964971
files = (
965972
5E5D77822040BD7D00EBC3A9 /* LogPolicyTests.swift in Sources */,
973+
5EF581552041387C00AC14FE /* CustomPlaygroundDisplayConvertibleTests.swift in Sources */,
966974
5EFE91D7203F6F8100E21BAA /* LegacyPlaygroundLoggerTests.swift in Sources */,
967975
);
968976
runOnlyForDeploymentPostprocessing = 0;

PlaygroundLogger/PlaygroundLogger/LogEntry+Reflection.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,14 @@ extension LogEntry {
3434
// Returns either the passed-in type name/summary or the type name/summary of `instance`.
3535
var typeName: String { return passedInTypeName ?? normalizedName(of: type(of: instance)) }
3636
var summary: String { return passedInSummary ?? String(describing: instance) }
37+
38+
// For types which conform to the `CustomPlaygroundDisplayConvertible` protocol, get their custom representation and then run it back through the initializer.
39+
if let customPlaygroundDisplayConvertible = instance as? CustomPlaygroundDisplayConvertible {
40+
self = try .init(describing: customPlaygroundDisplayConvertible.playgroundDescription, name: name, typeName: typeName, summary: nil, policy: policy, currentDepth: currentDepth)
41+
}
3742

38-
// For types which conform to the `CustomOpaqueLoggable` protocol, get their custom representation and construct an opaque log entry. (This is checked *second* so that user implementations of `CustomPlaygroundRepresentable` are honored over this framework's implementations of `CustomOpaqueLoggable`.)
39-
if let customOpaqueLoggable = instance as? CustomOpaqueLoggable {
43+
// For types which conform to the `CustomOpaqueLoggable` protocol, get their custom representation and construct an opaque log entry. (This is checked *second* so that user implementations of `CustomPlaygroundDisplayConvertible` are honored over this framework's implementations of `CustomOpaqueLoggable`.)
44+
else if let customOpaqueLoggable = instance as? CustomOpaqueLoggable {
4045
// TODO: figure out when to set `preferBriefSummary` to true
4146
self = try .opaque(name: name, typeName: typeName, summary: summary, preferBriefSummary: false, representation: customOpaqueLoggable.opaqueRepresentation())
4247
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===--- CustomPlaygroundDisplayConvertibleTests.swift --------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2018 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import XCTest
14+
@testable import PlaygroundLogger
15+
16+
import CoreGraphics
17+
18+
class CustomPlaygroundDisplayConvertibleTests: XCTestCase {
19+
func testBasicConformance() throws {
20+
struct MyPoint: CustomPlaygroundDisplayConvertible {
21+
let x: Int
22+
let y: Int
23+
24+
var playgroundDescription: Any {
25+
return CGPoint(x: x, y: y)
26+
}
27+
}
28+
29+
let point = MyPoint(x: 4, y: 3)
30+
31+
let logEntry = try LogEntry(describing: point, name: "point", policy: .default)
32+
33+
guard case let .opaque(name, typeName, _, _, representation) = logEntry else {
34+
XCTFail("Expected an instance of MyPoint to generate an opaque log entry")
35+
return
36+
}
37+
38+
XCTAssertEqual(name, "point")
39+
XCTAssert(typeName.hasSuffix(".MyPoint"))
40+
41+
guard let pointRepresentation = representation as? CGPoint else {
42+
XCTFail("Expected an instance of MyPoint to generate a CGPoint as its opaque representation")
43+
return
44+
}
45+
46+
XCTAssertEqual(pointRepresentation, CGPoint(x: 4, y: 3))
47+
}
48+
}

0 commit comments

Comments
 (0)