diff --git a/Sources/ConsoleKit/Activity/ActivityBar.swift b/Sources/ConsoleKit/Activity/ActivityBar.swift
index 05186c91..0aa52386 100644
--- a/Sources/ConsoleKit/Activity/ActivityBar.swift
+++ b/Sources/ConsoleKit/Activity/ActivityBar.swift
@@ -25,13 +25,13 @@ public protocol ActivityBar: ActivityIndicatorType {
extension ActivityBar {
/// See ``ActivityIndicatorType``.
public func outputActivityIndicator(to console: any Console, state: ActivityIndicatorState) {
- let bar: ConsoleText
- switch state {
- case .ready: bar = "[...]"
- case .active(let tick): bar = renderActiveBar(tick: tick, width: console.activityBarWidth)
- case .success: bar = "[Done]".consoleText(.success)
- case .failure: bar = "[Failed]".consoleText(.error)
- }
+ let bar: ConsoleText =
+ switch state {
+ case .ready: "[...]"
+ case .active(let tick): renderActiveBar(tick: tick, width: console.activityBarWidth)
+ case .success: "[Done]".consoleText(.success)
+ case .failure: "[Failed]".consoleText(.error)
+ }
console.output(title.consoleText(.plain) + " " + bar)
}
}
diff --git a/Sources/ConsoleKit/Activity/ActivityIndicator.swift b/Sources/ConsoleKit/Activity/ActivityIndicator.swift
index 30c44ec8..052d6443 100644
--- a/Sources/ConsoleKit/Activity/ActivityIndicator.swift
+++ b/Sources/ConsoleKit/Activity/ActivityIndicator.swift
@@ -20,13 +20,12 @@ extension ActivityIndicatorType {
/// let loadingBar = console.loadingBar(title: "Loading")
/// try await foo.withActivityIndicator {
/// try await Task.sleep(for: .seconds(2.5))
-/// return true
/// }
/// ```
///
public final class ActivityIndicator: Sendable where A: ActivityIndicatorType {
let _activity: Mutex
- /// The generic `ActivityIndicatorType` powering this `ActivityIndicator`.
+ /// The generic ``ActivityIndicatorType`` powering this ``ActivityIndicator``.
public var activity: A {
get {
self._activity.withLock { $0 }
@@ -36,25 +35,25 @@ public final class ActivityIndicator: Sendable where A: ActivityIndicatorType
}
}
- /// The `Console` this `ActivityIndicator` is running on.
+ /// The ``Console`` this ``ActivityIndicator`` is running on.
private let console: any Console
- /// Creates a new `ActivityIndicator`. Use `ActivityIndicatorType.newActivity(for:)`.
+ /// Creates a new ``ActivityIndicator``. Use ``ActivityIndicatorType/newActivity(for:)``.
init(activity: A, console: any Console) {
self.console = console
self._activity = Mutex(activity)
}
- /// Starts the `ActivityIndicator`. Usually this means beginning the associated "loading" animation.
+ /// Starts the ``ActivityIndicator``. Usually this means beginning the associated "loading" animation.
///
- /// Once started, `ActivityIndicator` will continue to redraw the `ActivityIndicatorType` at a fixed
- /// refresh rate passing `ActivityIndicatorState.active`.
+ /// Once started, ``ActivityIndicator`` will continue to redraw the ``ActivityIndicatorType`` at a fixed
+ /// refresh rate passing ``ActivityIndicatorState/active``.
///
/// - Parameters:
/// - refreshRate: The time interval (specified in milliseconds) to use
/// when updating the activity.
- private func start(refreshRate: Int = 40) async {
- guard console.supportsANSICommands else {
+ private func start(refreshRate: Int) async {
+ guard self.console.supportsANSICommands else {
// Skip animations if the console does not support ANSI commands
self.activity.outputActivityIndicator(to: self.console, state: .ready)
return
@@ -68,12 +67,6 @@ public final class ActivityIndicator: Sendable where A: ActivityIndicatorType
var tick: UInt = 0
- defer {
- if tick > 0 {
- self.console.popEphemeral()
- }
- }
-
for await _ in timer {
if tick > 0 {
self.console.popEphemeral()
@@ -84,32 +77,31 @@ public final class ActivityIndicator: Sendable where A: ActivityIndicatorType
}
}
- /// Stops the `ActivityIndicator`, yielding a failed / error appearance.
+ /// Stops the ``ActivityIndicator``, yielding a failed / error appearance.
///
- /// Passes `ActivityIndicatorState.failure` to the `ActivityIndicatorType`.
+ /// Passes ``ActivityIndicatorState/failure`` to the ``ActivityIndicatorType``.
///
- /// Must be called after `start(on:)` and completes the future returned by that method.
+ /// Must be called after ``ActivityIndicator/start(refreshRate:)``.
private func fail() {
- activity.outputActivityIndicator(to: console, state: .failure)
+ self.activity.outputActivityIndicator(to: console, state: .failure)
}
- /// Stops the `ActivityIndicator`, yielding a success / done appearance.
+ /// Stops the ``ActivityIndicator``, yielding a success / done appearance.
///
- /// Passes `ActivityIndicatorState.success` to the `ActivityIndicatorType`.
+ /// Passes ``ActivityIndicatorState/success`` to the ``ActivityIndicatorType``.
///
- /// Must be called after `start(on:)` and completes the future returned by that method.
+ /// Must be called after ``ActivityIndicator/start(refreshRate:)``.
private func succeed() {
- activity.outputActivityIndicator(to: console, state: .success)
+ self.activity.outputActivityIndicator(to: console, state: .success)
}
/// Starts the ``ActivityIndicator`` and stops it after the provided body completes.
///
- /// The body must return a `Bool` indicating whether the activity was successful or not.
- ///
/// - Parameters:
/// - refreshRate: The time interval (specified in milliseconds) to use when updating the activity.
/// - body: The asynchronous body to execute while the activity indicator is running.
- public func withActivityIndicator(refreshRate: Int = 40, _ body: () async throws -> Bool) async rethrows {
+ @discardableResult
+ public func withActivityIndicator(refreshRate: Int = 40, _ body: @Sendable () async throws -> T) async rethrows -> T {
let task = Task {
await self.start(refreshRate: refreshRate)
}
@@ -117,9 +109,18 @@ public final class ActivityIndicator: Sendable where A: ActivityIndicatorType
do {
let result = try await body()
task.cancel()
- result ? self.succeed() : self.fail()
+ _ = await task.result
+ if self.console.supportsANSICommands, self.console.depth > 0 {
+ self.console.popEphemeral()
+ }
+ self.succeed()
+ return result
} catch {
task.cancel()
+ _ = await task.result
+ if self.console.supportsANSICommands, self.console.depth > 0 {
+ self.console.popEphemeral()
+ }
self.fail()
throw error
}
diff --git a/Sources/ConsoleKit/Activity/ActivityIndicatorRenderer.swift b/Sources/ConsoleKit/Activity/ActivityIndicatorType.swift
similarity index 100%
rename from Sources/ConsoleKit/Activity/ActivityIndicatorRenderer.swift
rename to Sources/ConsoleKit/Activity/ActivityIndicatorType.swift
diff --git a/Sources/ConsoleKit/Activity/CustomActivity.swift b/Sources/ConsoleKit/Activity/CustomActivity.swift
index da0fbd2e..a74050c7 100644
--- a/Sources/ConsoleKit/Activity/CustomActivity.swift
+++ b/Sources/ConsoleKit/Activity/CustomActivity.swift
@@ -3,12 +3,11 @@ extension Console {
///
/// ```swift
/// // Create an activity indicator with the strings (frames) to loop over as it runs.
- /// let indicator = console.activity(frames: ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"])
+ /// let indicator = console.activity(title: "Loading", frames: ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"])
///
/// try await indicator.withActivityIndicator {
/// // complete the indicator after 3 seconds
/// try await Task.sleep(for: .seconds(3))
- /// return true
/// }
/// ```
///
@@ -16,6 +15,8 @@ extension Console {
/// https://github.com/kiliankoe/CLISpinner/blob/master/Sources/CLISpinner/Pattern.swift#L88-L151
///
/// - Parameters:
+ /// - title: The title of the activity indicator.
+ /// - titleAfterIndicator: If `true`, the title of the activity indicator will be printed after the indicator itself.
/// - frames: The strings to loop over as the activity indicator runs.
/// - success: The string to replace the indicator with when the operation succeeds. The default value is `[Done]`.
/// - failure: The string to replace the indicator with when the operation fails: The default value is `[Failed]`.
@@ -23,21 +24,32 @@ extension Console {
///
/// - Returns: An ``ActivityIndicator`` that can start and stop the indicator.
public func customActivity(
- frames: [String], success: String = "[Done]", failure: String = "[Failed]", color: ConsoleColor = .cyan
+ title: String,
+ titleAfterIndicator: Bool = true,
+ frames: [String],
+ success: String = "[Done]",
+ failure: String = "[Failed]",
+ color: ConsoleColor = .cyan
) -> ActivityIndicator {
- return CustomActivity(frames: frames, success: success, failure: failure, color: color).newActivity(for: self)
+ return CustomActivity(
+ title: title,
+ titleAfterIndicator: titleAfterIndicator,
+ frames: frames,
+ success: success,
+ failure: failure,
+ color: color
+ ).newActivity(for: self)
}
/// Creates an activity indicator with custom frames that are iterated over.
///
/// ```swift
/// // Create an activity indicator with the strings (frames) to loop over as it runs.
- /// let indicator = console.activity(frames: ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"])
+ /// let indicator = console.activity(title: "Loading", frames: ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"])
///
/// try await indicator.withActivityIndicator {
/// // complete the indicator after 3 seconds
/// try await Task.sleep(for: .seconds(3))
- /// return true
/// }
/// ```
///
@@ -45,22 +57,41 @@ extension Console {
/// https://github.com/kiliankoe/CLISpinner/blob/master/Sources/CLISpinner/Pattern.swift#L88-L151
///
/// - Parameters:
+ /// - title: The title of the activity indicator.
+ /// - titleAfterIndicator: If `true`, the title of the activity indicator will be printed after the indicator itself.
/// - frames: The text to loop over as the activity indicator runs.
/// - success: The string to replace the indicator with when the operation succeeds. The default value is `[Done]`.
/// - failure: The string to replace the indicator with when the operation fails: The default value is `[Failed]`.
///
/// - Returns: An ``ActivityIndicator`` that can start and stop the indicator.
public func customActivity(
- frames: [ConsoleText], success: String = "[Done]", failure: String = "[Failed]"
+ title: String,
+ titleAfterIndicator: Bool = true,
+ frames: [ConsoleText],
+ success: String = "[Done]",
+ failure: String = "[Failed]"
) -> ActivityIndicator {
- return CustomActivity(frames: frames, success: success, failure: failure).newActivity(for: self)
+ return CustomActivity(
+ title: title,
+ titleAfterIndicator: titleAfterIndicator,
+ frames: frames,
+ success: success,
+ failure: failure
+ ).newActivity(for: self)
}
}
/// An activity indicator with customizable frames and success and failure messages.
///
-/// See ``Console/customActivity(frames:success:failure:color:)`` to make one.
+/// See ``Console/customActivity(title:titleAfterIndicator:frames:success:failure:color:)`` to make one.
public struct CustomActivity: ActivityIndicatorType {
+ /// The title of the activity indicator.
+ public let title: String
+
+ /// If `true`, the title of the activity indicator will be printed after the indicator itself.
+ /// If `false`, the title will be printed before the indicator.
+ public let titleAfterIndicator: Bool
+
/// The text that will be output on the indicator ticks, each frame corresponding to a single tick in a range of `0...(frames.count - 1)`.
///
/// The index of the current frame is figured using the equation `tick % frames.count`, allowing the indicator to run indefinitely.
@@ -75,10 +106,20 @@ public struct CustomActivity: ActivityIndicatorType {
/// Creates a new ``CustomActivity`` instance.
///
/// - Parameters:
+ /// - title: The title of the activity indicator.
+ /// - titleAfterIndicator: If `true`, the title of the activity indicator will be printed after the indicator itself.
/// - frames: The text to loop over as the activity indicator runs.
/// - success: The string to replace the indicator with when the operation succeeds. The default value is `[Done]`.
/// - failure: The string to replace the indicator with when the operation fails: The default value is `[Failed]`.
- public init(frames: [ConsoleText], success: String = "[Done]", failure: String = "[Failed]") {
+ public init(
+ title: String,
+ titleAfterIndicator: Bool = true,
+ frames: [ConsoleText],
+ success: String = "[Done]",
+ failure: String = "[Failed]"
+ ) {
+ self.title = title
+ self.titleAfterIndicator = titleAfterIndicator
self.frames = frames.count > 0 ? frames : ["".consoleText(color: .cyan)]
self.success = success
self.failure = failure
@@ -87,25 +128,41 @@ public struct CustomActivity: ActivityIndicatorType {
/// Creates a new ``CustomActivity`` instance.
///
/// - Parameters:
+ /// - title: The title of the activity indicator.
+ /// - titleAfterIndicator: If `true`, the title of the activity indicator will be printed after the indicator itself.
/// - frames: The strings to loop over as the activity indicator runs.
/// - success: The string to replace the indicator with when the operation succeeds. The default value is `[Done]`.
/// - failure: The string to replace the indicator with when the operation fails: The default value is `[Failed]`.
/// - color: The color of text when the frames are displayed. The default value is `.cyan`.
- public init(frames: [String], success: String = "[Done]", failure: String = "[Failed]", color: ConsoleColor = .cyan) {
- self.init(frames: frames.map { $0.consoleText(color: color) }, success: success, failure: failure)
+ public init(
+ title: String,
+ titleAfterIndicator: Bool = true,
+ frames: [String],
+ success: String = "[Done]",
+ failure: String = "[Failed]",
+ color: ConsoleColor = .cyan
+ ) {
+ self.init(
+ title: title,
+ titleAfterIndicator: titleAfterIndicator,
+ frames: frames.map { $0.consoleText(color: color) },
+ success: success,
+ failure: failure
+ )
}
/// See ``ActivityIndicatorType/outputActivityIndicator(to:state:)``.
public func outputActivityIndicator(to console: any Console, state: ActivityIndicatorState) {
- let output: ConsoleText
-
- switch state {
- case .ready: output = frames[0]
- case .active(let tick): output = frames[Int(tick) % frames.count]
- case .success: output = self.success.consoleText(.success)
- case .failure: output = self.failure.consoleText(.error)
- }
+ let indicator: ConsoleText =
+ switch state {
+ case .ready: frames[0]
+ case .active(let tick): frames[Int(tick) % frames.count]
+ case .success: self.success.consoleText(.success)
+ case .failure: self.failure.consoleText(.error)
+ }
- console.output(output)
+ titleAfterIndicator
+ ? console.output(indicator + " " + title.consoleText(.plain))
+ : console.output(title.consoleText(.plain) + " " + indicator)
}
}
diff --git a/Sources/ConsoleKit/Activity/LoadingBar.swift b/Sources/ConsoleKit/Activity/LoadingBar.swift
index 94012d6a..5760e052 100644
--- a/Sources/ConsoleKit/Activity/LoadingBar.swift
+++ b/Sources/ConsoleKit/Activity/LoadingBar.swift
@@ -9,7 +9,6 @@ extension Console {
/// let loadingBar = console.loadingBar(title: "Loading")
/// try await loadingBar.withActivityIndicator {
/// try await Task.sleep(for: .seconds(3))
- /// return true
/// }
/// ```
///
@@ -30,7 +29,7 @@ extension Console {
/// See ``Console/loadingBar(title:)`` to create one.
public struct LoadingBar: ActivityBar {
/// See ``ActivityBar``.
- public var title: String
+ public let title: String
/// See ``ActivityBar``.
public func renderActiveBar(tick: UInt, width: Int) -> ConsoleText {
diff --git a/Sources/ConsoleKit/Activity/ProgressBar.swift b/Sources/ConsoleKit/Activity/ProgressBar.swift
index de39b0bb..ae00d10b 100644
--- a/Sources/ConsoleKit/Activity/ProgressBar.swift
+++ b/Sources/ConsoleKit/Activity/ProgressBar.swift
@@ -10,7 +10,7 @@ extension Console {
/// try await progressBar.withActivityIndicator {
/// while true {
/// if progressBar.activity.currentProgress >= 1.0 {
- /// return true
+ /// return
/// } else {
/// progressBar.activity.currentProgress += 0.1
/// try await Task.sleep(for: .seconds(0.25))
@@ -36,7 +36,7 @@ extension Console {
/// See ``Console/progressBar(title:)`` to create one.
public struct ProgressBar: ActivityBar {
/// See ``ActivityBar``.
- public var title: String
+ public let title: String
/// Controls how the ``ProgressBar`` is rendered.
///
@@ -60,3 +60,34 @@ public struct ProgressBar: ActivityBar {
return barComponents.joined(separator: "").consoleText(.info)
}
}
+
+extension ActivityIndicator where A == ProgressBar {
+ /// Starts the ``ActivityIndicator`` with a default refresh rate of 40 milliseconds.
+ ///
+ /// This method is a convenience wrapper around ``ActivityIndicator/withActivityIndicator(refreshRate:_:)-(_,()->T)``.
+ /// It passes the progress bar to the body closure, allowing you to update the `currentProgress` property as needed.
+ ///
+ /// ```swift
+ /// try await console.progressBar(title: "Downloading").withActivityIndicator { progressBar in
+ /// while true {
+ /// if progressBar.activity.currentProgress >= 1.0 {
+ /// return
+ /// } else {
+ /// progressBar.activity.currentProgress += 0.1
+ /// try await Task.sleep(for: .seconds(0.25))
+ /// }
+ /// }
+ /// }
+ /// ```
+ ///
+ /// See ``ActivityIndicator/withActivityIndicator(refreshRate:_:)-(_,()->T)`` for more information.
+ @discardableResult
+ public func withActivityIndicator(
+ refreshRate: Int = 40,
+ _ body: @Sendable (ActivityIndicator) async throws -> T
+ ) async rethrows -> T {
+ return try await self.withActivityIndicator(refreshRate: refreshRate) {
+ try await body(self)
+ }
+ }
+}
diff --git a/Sources/ConsoleKit/Clear/Console+Ephemeral.swift b/Sources/ConsoleKit/Clear/Console+Ephemeral.swift
index 8dd46600..c1055763 100644
--- a/Sources/ConsoleKit/Clear/Console+Ephemeral.swift
+++ b/Sources/ConsoleKit/Clear/Console+Ephemeral.swift
@@ -105,7 +105,7 @@ extension Console {
/// Tracks how many successive calls to ``Console/pushEphemeral()`` have been made.
///
/// Calling ``Console/popEphemeral()`` will decrement this number.
- private var depth: Int {
+ private(set) var depth: Int {
get { return (self.userInfo["depth"] as? Int) ?? 0 }
set { self.userInfo["depth"] = newValue }
}
diff --git a/Tests/ConsoleKitTests/ActivityTests.swift b/Tests/ConsoleKitTests/ActivityTests.swift
index 711b54ef..a29de6d2 100644
--- a/Tests/ConsoleKitTests/ActivityTests.swift
+++ b/Tests/ConsoleKitTests/ActivityTests.swift
@@ -1,7 +1,6 @@
+import ConsoleKit
import Testing
-@testable import ConsoleKit
-
@Suite("Activity Tests")
struct ActivityTests {
@Test("Loading")
@@ -11,7 +10,6 @@ struct ActivityTests {
try await foo.withActivityIndicator {
try await Task.sleep(for: .seconds(2.5))
- return false
}
enum TestError: Error {
@@ -32,7 +30,18 @@ struct ActivityTests {
try await foo.withActivityIndicator {
while true {
if foo.activity.currentProgress >= 1.0 {
- return true
+ return
+ } else {
+ foo.activity.currentProgress += 0.1
+ try await Task.sleep(for: .seconds(0.1))
+ }
+ }
+ }
+
+ try await console.progressBar(title: "Progress").withActivityIndicator { foo in
+ while true {
+ if foo.activity.currentProgress >= 1.0 {
+ return
} else {
foo.activity.currentProgress += 0.1
try await Task.sleep(for: .seconds(0.1))
@@ -45,11 +54,10 @@ struct ActivityTests {
func customIndicator() async throws {
let console = Terminal()
- let indicator = console.customActivity(frames: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"])
+ let indicator = console.customActivity(title: "Loading", frames: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"])
try await indicator.withActivityIndicator {
try await Task.sleep(for: .seconds(3))
- return true
}
}
@@ -58,23 +66,22 @@ struct ActivityTests {
let console = Terminal()
let frames: [ConsoleText] = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
- let indicator = console.customActivity(frames: frames)
+ let indicator = console.customActivity(title: "Loading", frames: frames)
try await indicator.withActivityIndicator {
try await Task.sleep(for: .seconds(3))
- return true
}
}
@Test("Activity Width Key")
func activityWidthKey() {
var dict = [AnySendableHashable: String]()
+ dict[AnySendableHashable("ConsoleKit.Tests")] = "string key"
- dict[AnySendableHashable(ActivityBarWidthKey())] = "width key"
- dict[AnySendableHashable("ConsoleKit.ActivityBarWidthKey")] = "string key"
-
- #expect(dict[AnySendableHashable(ActivityBarWidthKey())] == "width key")
- #expect(dict[AnySendableHashable("ConsoleKit.ActivityBarWidthKey")] == "string key")
+ #expect(dict[AnySendableHashable("ConsoleKit.Tests")] == "string key")
+ #expect(dict.keys.contains { $0.description == "ConsoleKit.Tests" })
+ #expect(dict.keys.contains { $0.debugDescription == "AnyHashable(\"ConsoleKit.Tests\")" })
+ #expect(dict.keys.first?.customMirror.displayStyle == nil)
let console = Terminal()
#expect(console.activityBarWidth == 25)
diff --git a/Tests/ConsoleKitTests/TerminalTests.swift b/Tests/ConsoleKitTests/TerminalTests.swift
index 143e6388..150b530c 100644
--- a/Tests/ConsoleKitTests/TerminalTests.swift
+++ b/Tests/ConsoleKitTests/TerminalTests.swift
@@ -5,29 +5,28 @@ import Testing
struct TerminalTests {
@Test("Stylize Foreground")
func stylizeForeground() throws {
- #expect("TEST".consoleStylized(.init(color: .black)) == "\u{001b}[0;30mTEST\u{001b}[0m")
+ #expect("TEST".consoleStylized(color: .black) == "\u{001b}[0;30mTEST\u{001b}[0m")
}
@Test("Stylize Background")
func stylizeBackground() throws {
- #expect("TEST".consoleStylized(.init(color: .white, background: .red)) == "\u{001b}[0;37;41mTEST\u{001b}[0m")
+ #expect("TEST".consoleStylized(color: .white, background: .red) == "\u{001b}[0;37;41mTEST\u{001b}[0m")
}
@Test("Stylize Bold")
func stylizeBold() throws {
- #expect("TEST".consoleStylized(.init(color: .white, isBold: true)) == "\u{001b}[0;1;37mTEST\u{001b}[0m")
+ #expect("TEST".consoleStylized(color: .white, isBold: true) == "\u{001b}[0;1;37mTEST\u{001b}[0m")
}
@Test("Stylize Only Bold")
func stylizeOnlyBold() throws {
- #expect("TEST".consoleStylized(.init(color: nil, isBold: true)) == "\u{001b}[0;1mTEST\u{001b}[0m")
+ #expect("TEST".consoleStylized(color: nil, isBold: true) == "\u{001b}[0;1mTEST\u{001b}[0m")
}
@Test("Stylize All Attributes")
func stylizeAllAttrs() throws {
#expect(
- "TEST".consoleStylized(.init(color: .brightWhite, background: .brightGreen, isBold: true))
- == "\u{001b}[0;1;97;102mTEST\u{001b}[0m"
+ "TEST".consoleStylized(color: .brightWhite, background: .brightGreen, isBold: true) == "\u{001b}[0;1;97;102mTEST\u{001b}[0m"
)
}
@@ -38,17 +37,17 @@ struct TerminalTests {
@Test("Stylize Palette Color")
func stylizePaletteColor() throws {
- #expect("TEST".consoleStylized(.init(color: .palette(100))) == "\u{001b}[0;38;5;100mTEST\u{001b}[0m")
- #expect("TEST".consoleStylized(.init(color: .white, background: .palette(100))) == "\u{001b}[0;37;48;5;100mTEST\u{001b}[0m")
+ #expect("TEST".consoleStylized(color: .palette(100)) == "\u{001b}[0;38;5;100mTEST\u{001b}[0m")
+ #expect("TEST".consoleStylized(color: .white, background: .palette(100)) == "\u{001b}[0;37;48;5;100mTEST\u{001b}[0m")
}
@Test("Stylize RGB Color")
func stylizeRGBColor() throws {
#expect(
- "TEST".consoleStylized(.init(color: .custom(r: 100, g: 100, b: 100))) == "\u{001b}[0;38;2;100;100;100mTEST\u{001b}[0m"
+ "TEST".consoleStylized(color: .custom(r: 100, g: 100, b: 100)) == "\u{001b}[0;38;2;100;100;100mTEST\u{001b}[0m"
)
#expect(
- "TEST".consoleStylized(.init(color: .white, background: .custom(r: 100, g: 100, b: 100)))
+ "TEST".consoleStylized(color: .white, background: .custom(r: 100, g: 100, b: 100))
== "\u{001b}[0;37;48;2;100;100;100mTEST\u{001b}[0m"
)
}