Skip to content

Commit

Permalink
Handle logs that have multiple lines
Browse files Browse the repository at this point in the history
  • Loading branch information
pepicrft committed Feb 21, 2025
1 parent 59d552d commit a786eb1
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 8 deletions.
19 changes: 11 additions & 8 deletions Sources/Noora/Components/CollapsibleStep.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,16 @@ struct CollapsibleStep {

func runInteractive() async throws {
renderInteractiveLines(lines: [])
var lines: [TerminalText] = []
var lines: [String] = []
do {
try await task { line in
lines.append(line)
if lines.count > visibleLines {
lines.removeFirst()
try await task { logs in
for logLine in logs.formatted(theme: theme, terminal: terminal).split(separator: "\n") {
lines.append(String(logLine))
if lines.count > visibleLines {
lines.removeFirst()
}
}

renderInteractiveLines(lines: lines)
}
} catch {
Expand Down Expand Up @@ -114,11 +117,11 @@ struct CollapsibleStep {
}
}

private func renderInteractiveLines(lines: [TerminalText]) {
private func renderInteractiveLines(lines: [String]) {
var content = "\(title.formatted(theme: theme, terminal: terminal))".hexIfColoredTerminal(theme.primary, terminal)
.boldIfColoredTerminal(terminal)
for (index, line) in lines.enumerated() {
content.append("\n \(line.formatted(theme: theme, terminal: terminal))")
for line in lines {
content.append("\n \(line)")
}
renderer.render(content, standardPipeline: standardPipelines.output)
}
Expand Down
36 changes: 36 additions & 0 deletions Tests/NooraTests/Components/CollapsibleStepTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,42 @@ struct CollapsibleStepTests {
""")
}

@Test func run_whenInteractive_andLogsAreMultiline() async throws {
// Given
let terminal = MockTerminal(isInteractive: true, isColored: false)
let subject = CollapsibleStep(
title: "Authentication",
successMessage: "Authenticated",
errorMessage: "Authentication failed",
visibleLines: 3,
task: { log in
// Multiline
log("Redirecting to the browser\nPress CTRL+C to interrupt the process")
},
theme: .test(),
terminal: terminal,
renderer: renderer,
standardPipelines: StandardPipelines()
)

// When
try await subject.run()

// Then
var renders = Array(renderer.renders.reversed())
#expect(renders.popLast() == """
◉ Authentication
""")
#expect(renders.popLast() == """
◉ Authentication
Redirecting to the browser
Press CTRL+C to interrupt the process
""")
#expect(renders.popLast() == """
✔︎ Authenticated
""")
}

@Test func run_whenNonInteractive() async throws {
// Given
let terminal = MockTerminal(isInteractive: false, isColored: false)
Expand Down

0 comments on commit a786eb1

Please sign in to comment.