Skip to content

Commit 0ebb71a

Browse files
riken127ricab
authored andcommitted
[cli] Print non-live spinner messages cleanly
When stdout is not live, keep callback-visible output while avoiding spinner control-sequence clutter. Make start(message) print only the message in non-live mode and return early in stop() for non-live mode. Keep print() behavior unchanged so log lines continue to be emitted by spinner callbacks. Add unit tests covering non-live logging, reply, and iterative spinner callbacks.
1 parent 077baf8 commit 0ebb71a

2 files changed

Lines changed: 57 additions & 7 deletions

File tree

src/client/cli/cmd/animated_spinner.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,17 @@ mp::AnimatedSpinner::~AnimatedSpinner()
4343
void mp::AnimatedSpinner::start(const std::string& start_message)
4444
{
4545
if (!is_live)
46+
{
47+
current_message = start_message;
48+
cout << start_message << std::flush;
4649
return;
50+
}
4751

4852
std::unique_lock<decltype(mutex)> lock{mutex};
4953
if (!running)
5054
{
5155
current_message = start_message;
5256
running = true;
53-
5457
clear_line(cout);
5558
cout << start_message << " " << std::flush;
5659
t = std::thread(&AnimatedSpinner::draw, this);
@@ -65,7 +68,7 @@ void mp::AnimatedSpinner::start()
6568

6669
void mp::AnimatedSpinner::stop()
6770
{
68-
if(!is_live)
71+
if (!is_live)
6972
return;
7073

7174
std::unique_lock<decltype(mutex)> lock{mutex};
@@ -77,16 +80,11 @@ void mp::AnimatedSpinner::stop()
7780
if (t.joinable())
7881
t.join();
7982
}
80-
81-
8283
clear_line(cout);
8384
}
8485

8586
void mp::AnimatedSpinner::print(std::ostream& stream, const std::string& message)
8687
{
87-
if (!is_live)
88-
return;
89-
9088
stop();
9189

9290
stream << message;

tests/unit/test_common_callbacks.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,55 @@ TEST_F(TestSpinnerCallbacks, confirmationCallbackAnswers)
199199
EXPECT_THAT(err.str(), IsEmpty());
200200
EXPECT_THAT(out.str(), clearStreamMatcher());
201201
}
202+
203+
TEST_F(TestSpinnerCallbacks, nonLiveLoggingSpinnerCallbackLogsWithoutSpinnerArtifacts)
204+
{
205+
constexpr auto log = "message in a bottle";
206+
mp::AnimatedSpinner non_live_spinner{out, false};
207+
208+
mp::MountReply reply;
209+
reply.set_log_line(log);
210+
211+
auto cb =
212+
mp::make_logging_spinner_callback<mp::MountRequest, mp::MountReply>(non_live_spinner, err);
213+
cb(reply, nullptr);
214+
215+
EXPECT_THAT(err.str(), StrEq(log));
216+
EXPECT_THAT(out.str(), IsEmpty());
217+
}
218+
219+
TEST_F(TestSpinnerCallbacks, nonLiveReplySpinnerCallbackPrintsAllMessagesWithoutSpinnerArtifacts)
220+
{
221+
constexpr auto log = "message in a bottle";
222+
constexpr auto msg = "answer";
223+
mp::AnimatedSpinner non_live_spinner{out, false};
224+
225+
mp::MountReply reply;
226+
reply.set_log_line(log);
227+
reply.set_reply_message(msg);
228+
229+
auto cb =
230+
mp::make_reply_spinner_callback<mp::MountRequest, mp::MountReply>(non_live_spinner, err);
231+
cb(reply, nullptr);
232+
233+
EXPECT_THAT(err.str(), StrEq(log));
234+
EXPECT_THAT(out.str(), StrEq(msg));
235+
}
236+
237+
TEST_F(TestSpinnerCallbacks, nonLiveIterativeSpinnerCallbackPrintsAllMessagesWithoutSpinnerArtifacts)
238+
{
239+
constexpr auto log = "message in a bottle";
240+
constexpr auto msg = "answer";
241+
mp::AnimatedSpinner non_live_spinner{out, false};
242+
243+
mp::MountReply reply;
244+
reply.set_log_line(log);
245+
reply.set_reply_message(msg);
246+
247+
auto cb = mp::make_iterative_spinner_callback<mp::MountRequest, mp::MountReply>(
248+
non_live_spinner, term);
249+
cb(reply, nullptr);
250+
251+
EXPECT_THAT(err.str(), StrEq(log));
252+
EXPECT_THAT(out.str(), StrEq(msg));
253+
}

0 commit comments

Comments
 (0)