mirror of
https://github.com/microsoft/PowerToys
synced 2024-11-22 00:03:48 +00:00
[PowerRename]Apostrophe handling in capitalize and titlecase modes (#32928)
* #(8796) Ignore capitalization if prevous character is an apostrophe. Updated Unit tests to test this change and added case sensitivity to unit tests when checking file and folder paths. * #8796 Perform case insensitive search for Titlecase exceptions in PowerRename. Updated Titlecase unit test to test changes * #8796 Accomodate single quoted words and leading single quote for PowerRename. * Updating unit tests to accomodate repository spell checking
This commit is contained in:
parent
eaf38ddcf6
commit
37059d4db0
@ -46,6 +46,11 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour
|
||||
{
|
||||
std::locale::global(std::locale(""));
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
|
||||
auto contractionOrSingleQuotedWordCheck = [](std::wstring stem, size_t i) {
|
||||
return !i || stem[i - 1] != '\'' || (i == 1 || iswpunct(stem[i - 2]) || iswspace(stem[i - 2]));
|
||||
};
|
||||
|
||||
if (source && flags)
|
||||
{
|
||||
if (flags & Uppercase)
|
||||
@ -156,7 +161,7 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour
|
||||
|
||||
for (size_t i = 0; i < stemLength; i++)
|
||||
{
|
||||
if (!i || iswspace(stem[i - 1]) || iswpunct(stem[i - 1]))
|
||||
if (!i || iswspace(stem[i - 1]) || (iswpunct(stem[i - 1]) && contractionOrSingleQuotedWordCheck(stem, i)))
|
||||
{
|
||||
if (iswspace(stem[i]) || iswpunct(stem[i]))
|
||||
{
|
||||
@ -167,7 +172,10 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour
|
||||
{
|
||||
wordLength++;
|
||||
}
|
||||
if (isFirstWord || i + wordLength == stemLength || std::find(exceptions.begin(), exceptions.end(), stem.substr(i, wordLength)) == exceptions.end())
|
||||
|
||||
auto subStr = stem.substr(i, wordLength);
|
||||
std::transform(subStr.begin(), subStr.end(), subStr.begin(), ::towlower);
|
||||
if (isFirstWord || i + wordLength == stemLength || std::find(exceptions.begin(), exceptions.end(), subStr) == exceptions.end())
|
||||
{
|
||||
stem[i] = towupper(stem[i]);
|
||||
isFirstWord = false;
|
||||
@ -205,13 +213,16 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour
|
||||
|
||||
for (size_t i = 0; i < stemLength; i++)
|
||||
{
|
||||
if (!i || iswspace(stem[i - 1]) || iswpunct(stem[i - 1]))
|
||||
if (!i || iswspace(stem[i - 1]) || (iswpunct(stem[i - 1]) && contractionOrSingleQuotedWordCheck(stem, i)))
|
||||
{
|
||||
if (iswspace(stem[i]) || iswpunct(stem[i]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
stem[i] = towupper(stem[i]);
|
||||
else
|
||||
{
|
||||
stem[i] = towupper(stem[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -91,11 +91,15 @@ namespace PowerRenameManagerTests
|
||||
|
||||
Assert::IsTrue(replaceSuccess);
|
||||
|
||||
std::vector<std::wstring> shouldRename = { L"not ", L"" };
|
||||
|
||||
// Verify the rename occurred
|
||||
for (int i = 0; i < numPairs; i++)
|
||||
{
|
||||
Assert::IsTrue(testFileHelper.PathExists(renamePairs[i].originalName) == !renamePairs[i].shouldRename);
|
||||
Assert::IsTrue(testFileHelper.PathExists(renamePairs[i].newName) == renamePairs[i].shouldRename);
|
||||
Assert::IsTrue(testFileHelper.PathExistsCaseSensitive(renamePairs[i].originalName) == !renamePairs[i].shouldRename,
|
||||
(std::wstring(L"The path: [" + renamePairs[i].originalName + L"] should ") + shouldRename[!renamePairs[i].shouldRename] + L"exist.").c_str());
|
||||
Assert::IsTrue(testFileHelper.PathExistsCaseSensitive(renamePairs[i].newName) == renamePairs[i].shouldRename,
|
||||
(std::wstring(L"The path: [" + renamePairs[i].newName + L"] should ") + shouldRename[renamePairs[i].shouldRename] + L"exist.").c_str());
|
||||
}
|
||||
|
||||
Assert::IsTrue(mgr->Shutdown() == S_OK);
|
||||
@ -250,7 +254,19 @@ namespace PowerRenameManagerTests
|
||||
TEST_METHOD (VerifyTitlecaseTransform)
|
||||
{
|
||||
rename_pairs renamePairs[] = {
|
||||
{ L"foo and the to", L"Bar and the To", false, true, 0 },
|
||||
{ L"foo And The To", L"Bar and the To", false, true, 0 },
|
||||
{ L"foo And The To.txt", L"Bar and the To.txt", true, true, 0 },
|
||||
{ L"Test", L"Test_norename", false, false, 0 }
|
||||
};
|
||||
|
||||
RenameHelper(renamePairs, ARRAYSIZE(renamePairs), L"foo", L"bar", SYSTEMTIME{ 2020, 7, 3, 22, 15, 6, 42, 453 }, DEFAULT_FLAGS | Titlecase);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyTitlecaseWithApostropheTransform)
|
||||
{
|
||||
rename_pairs renamePairs[] = {
|
||||
{ L"the foo i'll and i've you're dogs' the i'd it's i'm don't to y'all", L"The Bar I'll and I've You're Dogs' the I'd It's I'm Don't to Y'all", false, true, 0 },
|
||||
{ L"'the 'foo' 'i'll' and i've you're dogs' the 'i'd' it's i'm don't to y'all.txt", L"'The 'Bar' 'I'll' and I've You're Dogs' the 'I'd' It's I'm Don't to Y'all.txt", true, true, 0 },
|
||||
{ L"Test", L"Test_norename", false, false, 0 }
|
||||
};
|
||||
|
||||
@ -267,10 +283,22 @@ namespace PowerRenameManagerTests
|
||||
RenameHelper(renamePairs, ARRAYSIZE(renamePairs), L"foo", L"bar", SYSTEMTIME{ 2020, 7, 3, 22, 15, 6, 42, 453 }, DEFAULT_FLAGS | Capitalized);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyCapitalizedWithApostropheTransform)
|
||||
{
|
||||
rename_pairs renamePairs[] = {
|
||||
{ L"foo i'll and i've you're dogs' the i'd it's i'm don't to y'all", L"Bar I'll And I've You're Dogs' The I'd It's I'm Don't To Y'all", false, true, 0 },
|
||||
{ L"'foo i'll 'and' i've you're dogs' the i'd it's i'm don't to y'all.txt", L"'Bar I'll 'And' I've You're Dogs' The I'd It's I'm Don't To Y'all.txt", true, true, 0 },
|
||||
{ L"Test", L"Test_norename", false, false, 0 }
|
||||
};
|
||||
|
||||
RenameHelper(renamePairs, ARRAYSIZE(renamePairs), L"foo", L"bar", SYSTEMTIME{ 2020, 7, 3, 22, 15, 6, 42, 453 }, DEFAULT_FLAGS | Capitalized);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyNameOnlyTransform)
|
||||
{
|
||||
rename_pairs renamePairs[] = {
|
||||
{ L"foo.txt", L"BAR.txt", false, true, 0 },
|
||||
{ L"foo.foo", L"BAR.foo", true, true, 0 },
|
||||
{ L"foo.txt", L"BAR.TXT", false, true, 0 },
|
||||
{ L"TEST", L"TEST_norename", false, false, 1 }
|
||||
};
|
||||
|
||||
|
@ -47,6 +47,19 @@ bool CTestFileHelper::PathExists(_In_ const std::wstring path)
|
||||
return fs::exists(fullPath);
|
||||
}
|
||||
|
||||
bool CTestFileHelper::PathExistsCaseSensitive(_In_ const std::wstring path)
|
||||
{
|
||||
fs::path tempDirPath = fs::path(_tempDirectory);
|
||||
for (const auto& entry : fs::directory_iterator(tempDirPath))
|
||||
{
|
||||
if (entry.path().filename().wstring() == path)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CTestFileHelper::_CreateTempDirectory()
|
||||
{
|
||||
// Initialize to the temp directory
|
||||
|
@ -14,6 +14,7 @@ public:
|
||||
bool AddFolder(_In_ const std::wstring path);
|
||||
const std::filesystem::path GetTempDirectory() { return _tempDirectory; }
|
||||
bool PathExists(_In_ const std::wstring path);
|
||||
bool PathExistsCaseSensitive(_In_ const std::wstring path);
|
||||
std::filesystem::path GetFullPath(_In_ const std::wstring path);
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user