-
Notifications
You must be signed in to change notification settings - Fork 660
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor image vault utils #3846
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3846 +/- ##
==========================================
+ Coverage 89.02% 89.13% +0.11%
==========================================
Files 255 255
Lines 14583 14604 +21
==========================================
+ Hits 12982 13018 +36
+ Misses 1601 1586 -15 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good @Sploder12
Thanks for tackling this. This has needed to be cleaned up for a while.
f128abb
to
4ec3486
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Sploder12
Well done, I only have a few minor comments and questions.
using DefaultDecoderT = XzImageDecoder; | ||
|
||
virtual QString copy_to_dir(const QString& file, const QDir& output_dir) const; | ||
[[nodiscard]] virtual QString compute_hash(QIODevice& device) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comput_hash
function is used internally (except the unit test), do we have to expose that? Can it be a private function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be made protected nevermind
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it the only role of it is being called as sub-function of the other compute_file_hash
function? If so, I do not even see the point of unit testing that alone, because the unit test of compute_file_hash
should cover that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anyway, I do not have a strong opinion on this. Feel free to go either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My reasoning for making it was to make compute_file_hash
easier to unit test, since otherwise mocking would require a wrapper around the Qt hashing functions. Or it could use a real file for testing, but that tends to cause issues in CI so I wanted to avoid it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok I see now, basically QIODevice& device
acted as a dependency injection point so you can pass down buffer as opposed to a file. I think we can compromise on this in this particular case. But In general, exposing private function for unit testing should not be the norm. Because of breaking encapsulation and increasing the test brittleness.
|
||
virtual void verify_file_hash(const QString& file, const QString& hash) const; | ||
|
||
virtual QString extract_file(const QString& file, const Decoder& decoder, bool delete_original = false) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question about the exposure of this non-template extract_file
function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same response, in this case const Decoder& decoder
(a function object) is used as an injection point.
{ | ||
|
||
class MockImageDecoder | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice standalone mock class only for template parameter use.
new_image_path.remove(".xz"); | ||
QString mp::ImageVaultUtils::extract_file(const QString& file, const Decoder& decoder, bool delete_original) const | ||
{ | ||
const auto fs_new_path = MP_FILEOPS.remove_extension(file.toStdU16String()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why exactly do we need the toStdU16String
function as opposed to toStdString
? I thought the toStdString
checks the value type and return the corresponding string so it should be safe on windows, maybe I have missed something. Same question goes to fs_new_path.u8string()
called later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another wondering is the QString::toStdU16String
's behavior on linux, std::u16string
is the input string to construct fs::path
, will that be safe considering linux use UTF-8?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The path constructor overload for std::u16string
says "conversion from UTF-16 to native filesystem encoding is used" so it should be safe. While the std::string
constructor says "is assumed to be the native narrow encoding". This whole issue is probably why they added the std::u8string
overload in C++20 which has the same spec as std::u16string
, but with UTF-8
const auto image_filename = mp::vault::filename_for(image_url.path()); | ||
|
||
QFileInfo file_info{image_url.path()}; | ||
const auto image_filename = file_info.fileName(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we do one liner const auto image_filename = QFileInfo{image_url.path()}.fileName();
? Which is cleaner. Same goes to other occurrences of this pattern in the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did so for where I could. The places with remove
need an lvalue reference so a one liner won't work unless we change the API for the fileop.
This PR refactors several functions related to image vault utilities. All util functions now have unit test coverage and can be mocked to ease testing for components that use the utilities. Some functions have been removed or moved to file_ops since they already exist or fit better there.
MULTI-1653