Skip to content

Commit f2e299a

Browse files
authored
Merge pull request #26 from cwakamo/fix-large-sets
[PlaygroundLogger] Use `prefix` and `suffix` when getting the first and last n children for structured log entries.
2 parents 5f820dd + 80d27f6 commit f2e299a

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

PlaygroundLogger/PlaygroundLogger/LogEntry+Reflection.swift

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -222,17 +222,11 @@ extension Mirror {
222222
numberOfChildren = count
223223
}
224224

225-
let start = children.startIndex
226-
let max = children.index(start, offsetBy: numberOfChildren)
227-
228-
return superclassEntries + children[start..<max].map(logEntry(forChild:))
225+
return superclassEntries + children.prefix(numberOfChildren).map(logEntry(forChild:))
229226
}
230227

231228
func logEntries(forLastChildren count: Int) -> [LogEntry] {
232-
let max = children.endIndex
233-
let start = children.index(max, offsetBy: -count)
234-
235-
return children[start..<max].map(logEntry(forChild:))
229+
return children.suffix(count).map(logEntry(forChild:))
236230
}
237231

238232
// Ensure that our children are loggable (i.e. their depth is not prohibited by our current policy).

PlaygroundLogger/PlaygroundLoggerTests/LogEntryTests.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,46 @@ class LogEntryTests: XCTestCase {
8080
let encoder = LogEncoder()
8181
try logEntry.encode(with: encoder, format: .current)
8282
}
83+
84+
func testLargeSet() throws {
85+
let set = Set(1...1000)
86+
87+
let logEntry = try LogEntry(describing: set, name: "set", policy: .default)
88+
89+
guard case let .structured(name, _, _, totalChildrenCount, children, disposition) = logEntry else {
90+
XCTFail("Expected a structured log entry")
91+
return
92+
}
93+
94+
XCTAssertEqual(name, "set")
95+
96+
// We expect `totalChildrenCount` to be 1000 because `set` has 1000 elements.
97+
XCTAssertEqual(totalChildrenCount, 1000)
98+
99+
// We expect `children.count` to be 101 due to the default logging policy, which encodes the first 80 and the last 20 children when there's more than 100 children, plus a gap in between to indicate what was elided.
100+
XCTAssertEqual(children.count, 101)
101+
102+
for (index, childEntry) in children.enumerated() {
103+
if index == 80 {
104+
// We expect the 81st child to be a gap based on the default logging policy for containers.
105+
guard case .gap = childEntry else {
106+
XCTFail("Expected this entry to be a gap entry!")
107+
return
108+
}
109+
}
110+
else {
111+
// We expect all other children to be opaque entries representing the Ints in the set.
112+
guard case let .opaque(_, _, _, _, representation) = childEntry else {
113+
XCTFail("Expected this entry to be an opaque entry!")
114+
return
115+
}
116+
117+
// We don't know the precise value, due to hashing in the set.
118+
// But we *do* know that the value should be an Int64, so check that at least.
119+
XCTAssert(representation is Int64)
120+
}
121+
}
122+
123+
XCTAssertEqual(disposition, .membershipContainer)
124+
}
83125
}

0 commit comments

Comments
 (0)