Implement cpputils::ProgressBar
This commit is contained in:
parent
8a5091b8a2
commit
67e9885d10
@ -23,6 +23,7 @@ set(SOURCES
|
|||||||
io/IOStreamConsole.cpp
|
io/IOStreamConsole.cpp
|
||||||
io/NoninteractiveConsole.cpp
|
io/NoninteractiveConsole.cpp
|
||||||
io/pipestream.cpp
|
io/pipestream.cpp
|
||||||
|
io/ProgressBar.cpp
|
||||||
thread/LoopThread.cpp
|
thread/LoopThread.cpp
|
||||||
thread/ThreadSystem.cpp
|
thread/ThreadSystem.cpp
|
||||||
thread/debugging_nonwindows.cpp
|
thread/debugging_nonwindows.cpp
|
||||||
|
35
src/cpp-utils/io/ProgressBar.cpp
Normal file
35
src/cpp-utils/io/ProgressBar.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#include "ProgressBar.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
|
#include <mutex>
|
||||||
|
#include "IOStreamConsole.h"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
namespace cpputils {
|
||||||
|
|
||||||
|
ProgressBar::ProgressBar(const char* preamble, uint64_t max_value)
|
||||||
|
: ProgressBar(std::make_shared<IOStreamConsole>(), preamble, max_value) {}
|
||||||
|
|
||||||
|
ProgressBar::ProgressBar(std::shared_ptr<Console> console, const char* preamble, uint64_t max_value)
|
||||||
|
: _console(std::move(console))
|
||||||
|
, _preamble(string("\r") + preamble + " ")
|
||||||
|
, _max_value(max_value)
|
||||||
|
, _lastPercentage(std::numeric_limits<decltype(_lastPercentage)>::max()) {
|
||||||
|
ASSERT(_max_value > 0, "Progress bar can't handle max_value of 0");
|
||||||
|
|
||||||
|
_console->print("\n");
|
||||||
|
|
||||||
|
// show progress bar. _lastPercentage is different to zero, so it shows.
|
||||||
|
update(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProgressBar::update(uint64_t value) {
|
||||||
|
const size_t percentage = (100 * value) / _max_value;
|
||||||
|
if (percentage != _lastPercentage) {
|
||||||
|
_console->print(_preamble + std::to_string(percentage) + "%");
|
||||||
|
_lastPercentage = percentage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
31
src/cpp-utils/io/ProgressBar.h
Normal file
31
src/cpp-utils/io/ProgressBar.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef MESSMER_CPPUTILS_IO_PROGRESSBAR_H
|
||||||
|
#define MESSMER_CPPUTILS_IO_PROGRESSBAR_H
|
||||||
|
|
||||||
|
#include <cpp-utils/macros.h>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include "Console.h"
|
||||||
|
|
||||||
|
namespace cpputils {
|
||||||
|
|
||||||
|
class ProgressBar final {
|
||||||
|
public:
|
||||||
|
explicit ProgressBar(std::shared_ptr<Console> console, const char* preamble, uint64_t max_value);
|
||||||
|
explicit ProgressBar(const char* preamble, uint64_t max_value);
|
||||||
|
|
||||||
|
void update(uint64_t value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::shared_ptr<Console> _console;
|
||||||
|
std::string _preamble;
|
||||||
|
uint64_t _max_value;
|
||||||
|
size_t _lastPercentage;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ProgressBar);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -29,6 +29,7 @@ set(SOURCES
|
|||||||
io/ConsoleTest_Print.cpp
|
io/ConsoleTest_Print.cpp
|
||||||
io/ConsoleTest_Ask.cpp
|
io/ConsoleTest_Ask.cpp
|
||||||
io/ConsoleTest_AskPassword.cpp
|
io/ConsoleTest_AskPassword.cpp
|
||||||
|
io/ProgressBarTest.cpp
|
||||||
random/RandomIncludeTest.cpp
|
random/RandomIncludeTest.cpp
|
||||||
lock/LockPoolIncludeTest.cpp
|
lock/LockPoolIncludeTest.cpp
|
||||||
lock/ConditionBarrierIncludeTest.cpp
|
lock/ConditionBarrierIncludeTest.cpp
|
||||||
|
66
test/cpp-utils/io/ProgressBarTest.cpp
Normal file
66
test/cpp-utils/io/ProgressBarTest.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include <cpp-utils/io/ProgressBar.h>
|
||||||
|
#include <gmock/gmock.h>
|
||||||
|
|
||||||
|
using cpputils::ProgressBar;
|
||||||
|
using std::make_shared;
|
||||||
|
|
||||||
|
class MockConsole final: public cpputils::Console {
|
||||||
|
public:
|
||||||
|
void EXPECT_OUTPUT(const char* expected) {
|
||||||
|
EXPECT_EQ(expected, _output);
|
||||||
|
_output = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(const std::string& text) override {
|
||||||
|
_output += text;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ask(const std::string&, const std::vector<std::string>&) override {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool askYesNo(const std::string&, bool) override {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string askPassword(const std::string&) override {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string _output;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(ProgressBarTest, testProgressBar) {
|
||||||
|
auto console = make_shared<MockConsole>();
|
||||||
|
|
||||||
|
ProgressBar bar(console, "Preamble", 2000);
|
||||||
|
console->EXPECT_OUTPUT("\n\rPreamble 0%");
|
||||||
|
|
||||||
|
// when updating to 0, doesn't reprint
|
||||||
|
bar.update(0);
|
||||||
|
console->EXPECT_OUTPUT("");
|
||||||
|
|
||||||
|
// update to half
|
||||||
|
bar.update(1000);
|
||||||
|
console->EXPECT_OUTPUT("\rPreamble 50%");
|
||||||
|
|
||||||
|
// when updating to same value, doesn't reprint
|
||||||
|
bar.update(1000);
|
||||||
|
console->EXPECT_OUTPUT("");
|
||||||
|
|
||||||
|
// when updating to value with same percentage, doesn't reprint
|
||||||
|
bar.update(1001);
|
||||||
|
console->EXPECT_OUTPUT("");
|
||||||
|
|
||||||
|
// update to 0
|
||||||
|
bar.update(0);
|
||||||
|
console->EXPECT_OUTPUT("\rPreamble 0%");
|
||||||
|
|
||||||
|
// update to full
|
||||||
|
bar.update(2000);
|
||||||
|
console->EXPECT_OUTPUT("\rPreamble 100%");
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user