Skip to content

Commit 81a74d7

Browse files
committed
TextState: DebugOutputConvertible (#421)
* Fix debug text * XML * wip * wip * wip
1 parent 6421471 commit 81a74d7

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

Sources/ComposableArchitecture/SwiftUI/TextState.swift

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,4 +310,73 @@
310310
self.formatted().debugDescription
311311
}
312312
}
313+
314+
@available(iOS 13, macOS 10.15, macCatalyst 13, tvOS 13, watchOS 6, *)
315+
extension TextState: CustomDebugOutputConvertible {
316+
public var debugOutput: String {
317+
func debugOutputHelp(_ textState: Self) -> String {
318+
var output: String
319+
switch textState.storage {
320+
case let .concatenated(lhs, rhs):
321+
output = debugOutputHelp(lhs) + debugOutputHelp(rhs)
322+
case let .localized(key, tableName, bundle, comment):
323+
output = key.formatted(tableName: tableName, bundle: bundle, comment: comment)
324+
case let .verbatim(string):
325+
output = string
326+
}
327+
for modifier in textState.modifiers {
328+
switch modifier {
329+
case let .baselineOffset(baselineOffset):
330+
output = "<baseline-offset=\(baselineOffset)>\(output)</baseline-offset>"
331+
case .bold, .fontWeight(.some(.bold)):
332+
output = "**\(output)**"
333+
case .font(.some):
334+
break // TODO: capture Font description using DSL similar to TextState and print here
335+
case let .fontWeight(.some(weight)):
336+
func describe(weight: Font.Weight) -> String {
337+
switch weight {
338+
case .black: return "black"
339+
case .bold: return "bold"
340+
case .heavy: return "heavy"
341+
case .light: return "light"
342+
case .medium: return "medium"
343+
case .regular: return "regular"
344+
case .semibold: return "semibold"
345+
case .thin: return "thin"
346+
default: return "\(weight)"
347+
}
348+
}
349+
output = "<font-weight=\(describe(weight: weight))>\(output)</font-weight>"
350+
case let .foregroundColor(.some(color)):
351+
output = "<foreground-color=\(color)>\(output)</foreground-color>"
352+
case .italic:
353+
output = "_\(output)_"
354+
case let .kerning(kerning):
355+
output = "<kerning=\(kerning)>\(output)</kerning>"
356+
case let .strikethrough(active: true, color: .some(color)):
357+
output = "<s color=\(color)>\(output)</s>"
358+
case .strikethrough(active: true, color: .none):
359+
output = "~~\(output)~~"
360+
case let .tracking(tracking):
361+
output = "<tracking=\(tracking)>\(output)</tracking>"
362+
case let .underline(active: true, color):
363+
output = "<u\(color.map { " color=\($0)" } ?? "")>\(output)</u>"
364+
case .font(.none),
365+
.fontWeight(.none),
366+
.foregroundColor(.none),
367+
.strikethrough(active: false, color: _),
368+
.underline(active: false, color: _):
369+
break
370+
}
371+
}
372+
return output
373+
}
374+
375+
return #"""
376+
\#(Self.self)(
377+
\#(debugOutputHelp(self).indent(by: 2))
378+
)
379+
"""#
380+
}
381+
}
313382
#endif

Tests/ComposableArchitectureTests/DebugTests.swift

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,73 @@ final class DebugTests: XCTestCase {
344344
)
345345
}
346346

347+
func testTextState() {
348+
XCTAssertEqual(
349+
debugOutput(
350+
TextState("Hello, world!")
351+
),
352+
"""
353+
TextState(
354+
Hello, world!
355+
)
356+
"""
357+
)
358+
359+
XCTAssertEqual(
360+
debugOutput(
361+
TextState("Hello, ")
362+
+ TextState("world").bold().italic()
363+
+ TextState("!")
364+
),
365+
"""
366+
TextState(
367+
Hello, _**world**_!
368+
)
369+
"""
370+
)
371+
372+
XCTAssertEqual(
373+
debugOutput(
374+
TextState("Offset by 10.5").baselineOffset(10.5)
375+
+ TextState("\n") + TextState("Headline").font(.headline)
376+
+ TextState("\n") + TextState("No font").font(nil)
377+
+ TextState("\n") + TextState("Light font weight").fontWeight(.light)
378+
+ TextState("\n") + TextState("No font weight").fontWeight(nil)
379+
+ TextState("\n") + TextState("Red").foregroundColor(.red)
380+
+ TextState("\n") + TextState("No color").foregroundColor(nil)
381+
+ TextState("\n") + TextState("Italic").italic()
382+
+ TextState("\n") + TextState("Kerning of 2.5").kerning(2.5)
383+
+ TextState("\n") + TextState("Stricken").strikethrough()
384+
+ TextState("\n") + TextState("Stricken green").strikethrough(color: .green)
385+
+ TextState("\n") + TextState("Not stricken blue").strikethrough(false, color: .blue)
386+
+ TextState("\n") + TextState("Tracking of 5.5").tracking(5.5)
387+
+ TextState("\n") + TextState("Underlined").underline()
388+
+ TextState("\n") + TextState("Underlined pink").underline(color: .pink)
389+
+ TextState("\n") + TextState("Not underlined purple").underline(false, color: .pink)
390+
),
391+
"""
392+
TextState(
393+
<baseline-offset=10.5>Offset by 10.5</baseline-offset>
394+
Headline
395+
No font
396+
<font-weight=light>Light font weight</font-weight>
397+
No font weight
398+
<foreground-color=red>Red</foreground-color>
399+
No color
400+
_Italic_
401+
<kerning=2.5>Kerning of 2.5</kerning>
402+
~~Stricken~~
403+
<s color=green>Stricken green</s>
404+
Not stricken blue
405+
<tracking=5.5>Tracking of 5.5</tracking>
406+
<u>Underlined</u>
407+
<u color=pink>Underlined pink</u>
408+
Not underlined purple
409+
)
410+
"""
411+
)
412+
}
413+
347414
func testEffectOutput() {
348415
// XCTAssertEqual(
349416
// Effect<Int, Never>(value: 42)

0 commit comments

Comments
 (0)