Skip to content

Commit cb080b7

Browse files
authored
TextState: DebugOutputConvertible (#421)
* Fix debug text * XML * wip * wip * wip
1 parent a116fff commit cb080b7

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

Sources/ComposableArchitecture/SwiftUI/TextState.swift

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

Tests/ComposableArchitectureTests/DebugTests.swift

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

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

0 commit comments

Comments
 (0)