mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 03:37:59 +01:00
[PowerRename] Introduce advanced counter functionality (#27895)
This commit is contained in:
1
.github/actions/spell-check/expect.txt
vendored
1
.github/actions/spell-check/expect.txt
vendored
@@ -2003,6 +2003,7 @@ unregistering
|
||||
unremapped
|
||||
unsubscribe
|
||||
unvirtualized
|
||||
unwide
|
||||
UOffset
|
||||
UOI
|
||||
Updatelayout
|
||||
|
||||
@@ -54,3 +54,12 @@ inline void replace_chars(std::basic_string<CharT>& s,
|
||||
std::replace(begin(s), end(s), c, replacement_char);
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string unwide(const std::wstring& wide)
|
||||
{
|
||||
std::string result(wide.length(), 0);
|
||||
std::transform(begin(wide), end(wide), result.begin(), [](const wchar_t c) {
|
||||
return static_cast<char>(c);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace PowerRenameUI
|
||||
ExplorerItemsSource ExplorerItems { get; };
|
||||
Windows.Foundation.Collections.IObservableVector<PatternSnippet> SearchRegExShortcuts { get; };
|
||||
Windows.Foundation.Collections.IObservableVector<PatternSnippet> DateTimeShortcuts { get; };
|
||||
Windows.Foundation.Collections.IObservableVector<PatternSnippet> CounterShortcuts { get; };
|
||||
|
||||
String OriginalCount;
|
||||
String RenamedCount;
|
||||
|
||||
@@ -323,6 +323,8 @@
|
||||
<Flyout x:Name="DateTimeFlyout" ShouldConstrainToRootBounds="False">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
@@ -364,7 +366,45 @@
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
|
||||
<TextBlock x:Uid="CounterCheatSheet_Title"
|
||||
Margin="0,10,0,0"
|
||||
FontWeight="SemiBold" Grid.Row="2" />
|
||||
<ListView Margin="-4,12,0,0"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="DateTimeItemClick"
|
||||
ItemsSource="{x:Bind CounterShortcuts}"
|
||||
SelectionMode="None" Grid.Row="3">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate
|
||||
x:DataType="local:PatternSnippet">
|
||||
<Grid Margin="-10,0,0,0"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition
|
||||
Width="Auto" />
|
||||
<ColumnDefinition
|
||||
Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Padding="8"
|
||||
HorizontalAlignment="Left"
|
||||
Background="{ThemeResource ButtonBackground}"
|
||||
BorderBrush="{ThemeResource ButtonBorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="4">
|
||||
<TextBlock
|
||||
FontFamily="Consolas"
|
||||
Foreground="{ThemeResource ButtonForeground}"
|
||||
Text="{x:Bind Code}" />
|
||||
</Border>
|
||||
<TextBlock Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{x:Bind Description}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</Grid>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
|
||||
@@ -196,6 +196,13 @@ namespace winrt::PowerRenameUI::implementation
|
||||
m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L"$ff", manager.MainResourceMap().GetValue(L"Resources/DateTimeCheatSheet_MilliSeconds2D").ValueAsString()));
|
||||
m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L"$f", manager.MainResourceMap().GetValue(L"Resources/DateTimeCheatSheet_MilliSeconds1D").ValueAsString()));
|
||||
|
||||
m_CounterShortcuts = winrt::single_threaded_observable_vector<PowerRenameUI::PatternSnippet>();
|
||||
m_CounterShortcuts.Append(winrt::make<PatternSnippet>(L"${}", manager.MainResourceMap().GetValue(L"Resources/CounterCheatSheet_Simple").ValueAsString()));
|
||||
m_CounterShortcuts.Append(winrt::make<PatternSnippet>(L"${start=10}", manager.MainResourceMap().GetValue(L"Resources/CounterCheatSheet_Start").ValueAsString()));
|
||||
m_CounterShortcuts.Append(winrt::make<PatternSnippet>(L"${increment=5}", manager.MainResourceMap().GetValue(L"Resources/CounterCheatSheet_Increment").ValueAsString()));
|
||||
m_CounterShortcuts.Append(winrt::make<PatternSnippet>(L"${padding=8}", manager.MainResourceMap().GetValue(L"Resources/CounterCheatSheet_Padding").ValueAsString()));
|
||||
m_CounterShortcuts.Append(winrt::make<PatternSnippet>(L"${increment=3,padding=4,start=900}", manager.MainResourceMap().GetValue(L"Resources/CounterCheatSheet_Complex").ValueAsString()));
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
listView_ExplorerItems().ApplyTemplate();
|
||||
|
||||
@@ -81,6 +81,8 @@ namespace winrt::PowerRenameUI::implementation
|
||||
PowerRenameUI::ExplorerItemsSource ExplorerItems() { return m_explorerItems; }
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<PowerRenameUI::PatternSnippet> SearchRegExShortcuts() { return m_searchRegExShortcuts; }
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<PowerRenameUI::PatternSnippet> DateTimeShortcuts() { return m_dateTimeShortcuts; }
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<PowerRenameUI::PatternSnippet> CounterShortcuts() { return m_CounterShortcuts; }
|
||||
|
||||
hstring OriginalCount();
|
||||
void OriginalCount(hstring value);
|
||||
hstring RenamedCount();
|
||||
@@ -100,6 +102,7 @@ namespace winrt::PowerRenameUI::implementation
|
||||
PowerRenameUI::ExplorerItemsSource m_explorerItems;
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<PowerRenameUI::PatternSnippet> m_searchRegExShortcuts;
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<PowerRenameUI::PatternSnippet> m_dateTimeShortcuts;
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<PowerRenameUI::PatternSnippet> m_CounterShortcuts;
|
||||
|
||||
// Used by PowerRenameManagerEvents
|
||||
HRESULT OnRename(_In_ IPowerRenameItem* renameItem);
|
||||
|
||||
@@ -150,6 +150,24 @@
|
||||
<data name="ReplaceBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Replace with</value>
|
||||
</data>
|
||||
<data name="CounterCheatSheet_Title.Text" xml:space="preserve">
|
||||
<value>Replace using advanced counter syntax.</value>
|
||||
</data>
|
||||
<data name="CounterCheatSheet_Simple" xml:space="preserve">
|
||||
<value>A simple counter that you can use anywhere in a replace string.</value>
|
||||
</data>
|
||||
<data name="CounterCheatSheet_Start" xml:space="preserve">
|
||||
<value>A counter with a customized start value.</value>
|
||||
</data>
|
||||
<data name="CounterCheatSheet_Increment" xml:space="preserve">
|
||||
<value>A counter with a customized increment value.</value>
|
||||
</data>
|
||||
<data name="CounterCheatSheet_Padding" xml:space="preserve">
|
||||
<value>A counter with a customized number of leading padding zeroes.</value>
|
||||
</data>
|
||||
<data name="CounterCheatSheet_Complex" xml:space="preserve">
|
||||
<value>A counter showing multiple customized properties.</value>
|
||||
</data>
|
||||
<data name="DateTimeCheatSheet_Title.Text" xml:space="preserve">
|
||||
<value>Replace using file creation date and time</value>
|
||||
</data>
|
||||
|
||||
46
src/modules/powerrename/lib/Enumerating.cpp
Normal file
46
src/modules/powerrename/lib/Enumerating.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <pch.h>
|
||||
|
||||
#include "Enumerating.h"
|
||||
|
||||
#include <common\utils\string_utils.h>
|
||||
|
||||
std::vector<EnumOptions> parseEnumOptions(const std::wstring& replaceWith)
|
||||
{
|
||||
static const std::wregex enumStartRegex(LR"(start=(\d+))");
|
||||
static const std::wregex enumIncrementRegex(LR"(increment=(-?\d+))");
|
||||
static const std::wregex enumPaddingRegex(LR"(padding=(\d+))");
|
||||
|
||||
std::string buf;
|
||||
std::vector<EnumOptions> options;
|
||||
std::wregex enumGroupRegex(LR"(\$\{.*?\})");
|
||||
for (std::wsregex_iterator i{ begin(replaceWith), end(replaceWith), enumGroupRegex }, end; i != end; ++i)
|
||||
{
|
||||
std::wsmatch match = *i;
|
||||
std::wstring matchString = match.str();
|
||||
|
||||
EnumOptions option;
|
||||
option.replaceStrSpan.offset = match.position();
|
||||
option.replaceStrSpan.length = match.length();
|
||||
|
||||
std::wsmatch subMatch;
|
||||
if (std::regex_search(matchString, subMatch, enumStartRegex))
|
||||
{
|
||||
buf = unwide(subMatch[1].str());
|
||||
std::from_chars(buf.data(), buf.data() + buf.size(), option.start.emplace());
|
||||
}
|
||||
if (std::regex_search(matchString, subMatch, enumIncrementRegex))
|
||||
{
|
||||
buf = unwide(subMatch[1].str());
|
||||
std::from_chars(buf.data(), buf.data() + buf.size(), option.increment.emplace());
|
||||
}
|
||||
if (std::regex_search(matchString, subMatch, enumPaddingRegex))
|
||||
{
|
||||
buf = unwide(subMatch[1].str());
|
||||
std::from_chars(buf.data(), buf.data() + buf.size(), option.padding.emplace());
|
||||
}
|
||||
|
||||
options.emplace_back(std::move(option));
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
55
src/modules/powerrename/lib/Enumerating.h
Normal file
55
src/modules/powerrename/lib/Enumerating.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
struct EnumSpan
|
||||
{
|
||||
size_t offset = 0;
|
||||
size_t length = 0;
|
||||
};
|
||||
|
||||
struct EnumOptions
|
||||
{
|
||||
std::optional<int> start;
|
||||
std::optional<int> increment;
|
||||
std::optional<uint32_t> padding;
|
||||
|
||||
EnumSpan replaceStrSpan;
|
||||
|
||||
std::strong_ordering operator<=>(const EnumOptions& rhs) const noexcept
|
||||
{
|
||||
return std::make_tuple(start, increment, padding) <=> std::make_tuple(rhs.start, rhs.increment, rhs.padding);
|
||||
}
|
||||
|
||||
bool operator==(const EnumOptions& rhs) const noexcept
|
||||
{
|
||||
return std::make_tuple(start, increment, padding) == std::make_tuple(rhs.start, rhs.increment, rhs.padding);
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<EnumOptions> parseEnumOptions(const std::wstring& replaceWith);
|
||||
|
||||
struct Enumerator
|
||||
{
|
||||
inline Enumerator(EnumOptions options) :
|
||||
start{ options.start.value_or(0) }, increment{ options.increment.value_or(1) }, padding{ options.padding.value_or(0) }, replaceStrSpan{ options.replaceStrSpan }
|
||||
{
|
||||
}
|
||||
|
||||
inline int32_t enumerate(const unsigned long index) const { return start + static_cast<int32_t>(index * increment); }
|
||||
|
||||
inline size_t printTo(wchar_t* buf, const size_t bufSize, const unsigned long index) const
|
||||
{
|
||||
const int32_t enumeratedIndex = enumerate(index);
|
||||
wchar_t format[32];
|
||||
swprintf_s(format, sizeof(format) / sizeof(wchar_t), L"%%0%ud", padding);
|
||||
return swprintf_s(buf, bufSize, format, enumeratedIndex);
|
||||
}
|
||||
|
||||
EnumSpan replaceStrSpan;
|
||||
|
||||
private:
|
||||
int start;
|
||||
int increment;
|
||||
uint32_t padding;
|
||||
};
|
||||
@@ -237,12 +237,10 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour
|
||||
bool isFileTimeUsed(_In_ PCWSTR source)
|
||||
{
|
||||
bool used = false;
|
||||
std::wstring patterns[] = { L"(([^\\$]|^)(\\$\\$)*)\\$Y", L"(([^\\$]|^)(\\$\\$)*)\\$M", L"(([^\\$]|^)(\\$\\$)*)\\$D",
|
||||
L"(([^\\$]|^)(\\$\\$)*)\\$h", L"(([^\\$]|^)(\\$\\$)*)\\$m", L"(([^\\$]|^)(\\$\\$)*)\\$s", L"(([^\\$]|^)(\\$\\$)*)\\$f" };
|
||||
size_t patternsLength = ARRAYSIZE(patterns);
|
||||
for (size_t i = 0; !used && i < patternsLength; i++)
|
||||
static const std::array patterns = { std::wregex{ L"(([^\\$]|^)(\\$\\$)*)\\$Y" }, std::wregex{ L"(([^\\$]|^)(\\$\\$)*)\\$M" }, std::wregex{ L"(([^\\$]|^)(\\$\\$)*)\\$D" }, std::wregex{ L"(([^\\$]|^)(\\$\\$)*)\\$h" }, std::wregex{ L"(([^\\$]|^)(\\$\\$)*)\\$m" }, std::wregex{ L"(([^\\$]|^)(\\$\\$)*)\\$s" }, std::wregex{ L"(([^\\$]|^)(\\$\\$)*)\\$f" } };
|
||||
for (size_t i = 0; !used && i < patterns.size(); i++)
|
||||
{
|
||||
if (std::regex_search(source, std::wregex(patterns[i])))
|
||||
if (std::regex_search(source, patterns[i]))
|
||||
{
|
||||
used = true;
|
||||
}
|
||||
@@ -328,10 +326,10 @@ HRESULT GetDatedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source, SY
|
||||
StringCchPrintf(replaceTerm, MAX_PATH, TEXT("%s%03d"), L"$01", fileTime.wMilliseconds);
|
||||
res = regex_replace(res, std::wregex(L"(([^\\$]|^)(\\$\\$)*)\\$fff"), replaceTerm);
|
||||
|
||||
StringCchPrintf(replaceTerm, MAX_PATH, TEXT("%s%02d"), L"$01", fileTime.wMilliseconds/10);
|
||||
StringCchPrintf(replaceTerm, MAX_PATH, TEXT("%s%02d"), L"$01", fileTime.wMilliseconds / 10);
|
||||
res = regex_replace(res, std::wregex(L"(([^\\$]|^)(\\$\\$)*)\\$ff"), replaceTerm);
|
||||
|
||||
StringCchPrintf(replaceTerm, MAX_PATH, TEXT("%s%d"), L"$01", fileTime.wMilliseconds/100);
|
||||
StringCchPrintf(replaceTerm, MAX_PATH, TEXT("%s%d"), L"$01", fileTime.wMilliseconds / 100);
|
||||
res = regex_replace(res, std::wregex(L"(([^\\$]|^)(\\$\\$)*)\\$f"), replaceTerm);
|
||||
|
||||
hr = StringCchCopy(result, cchMax, res.c_str());
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
IFACEMETHOD(PutFlags)(_In_ DWORD flags) = 0;
|
||||
IFACEMETHOD(PutFileTime)(_In_ SYSTEMTIME fileTime) = 0;
|
||||
IFACEMETHOD(ResetFileTime)() = 0;
|
||||
IFACEMETHOD(Replace)(_In_ PCWSTR source, _Outptr_ PWSTR* result) = 0;
|
||||
IFACEMETHOD(Replace)(_In_ PCWSTR source, _Outptr_ PWSTR* result, unsigned long& enumIndex) = 0;
|
||||
};
|
||||
|
||||
interface __declspec(uuid("C7F59201-4DE1-4855-A3A2-26FC3279C8A5")) IPowerRenameItem : public IUnknown
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Enumerating.h" />
|
||||
<ClInclude Include="Helpers.h" />
|
||||
<ClInclude Include="MRUListHandler.h" />
|
||||
<ClInclude Include="PowerRenameEnum.h" />
|
||||
@@ -47,6 +48,7 @@
|
||||
<ClInclude Include="trace.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Enumerating.cpp" />
|
||||
<ClCompile Include="Helpers.cpp" />
|
||||
<ClCompile Include="MRUListHandler.cpp" />
|
||||
<ClCompile Include="PowerRenameEnum.cpp" />
|
||||
|
||||
@@ -923,7 +923,7 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv)
|
||||
winrt::check_hresult(pwtd->spsrm->GetRenameRegEx(&spRenameRegEx));
|
||||
|
||||
UINT itemCount = 0;
|
||||
unsigned long itemEnumIndex = 1;
|
||||
unsigned long itemEnumIndex = 0;
|
||||
winrt::check_hresult(pwtd->spsrm->GetItemCount(&itemCount));
|
||||
|
||||
for (UINT u = 0; u < itemCount; u++)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "pch.h"
|
||||
#include "PowerRenameRegEx.h"
|
||||
#include "Enumerating.h"
|
||||
#include "Settings.h"
|
||||
#include <regex>
|
||||
#include <string>
|
||||
@@ -7,15 +8,17 @@
|
||||
#include <boost/regex.hpp>
|
||||
#include <helpers.h>
|
||||
|
||||
using namespace std;
|
||||
using std::conditional_t;
|
||||
using std::regex_error;
|
||||
|
||||
IFACEMETHODIMP_(ULONG) CPowerRenameRegEx::AddRef()
|
||||
IFACEMETHODIMP_(ULONG)
|
||||
CPowerRenameRegEx::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_refCount);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG) CPowerRenameRegEx::Release()
|
||||
IFACEMETHODIMP_(ULONG)
|
||||
CPowerRenameRegEx::Release()
|
||||
{
|
||||
long refCount = InterlockedDecrement(&m_refCount);
|
||||
|
||||
@@ -127,6 +130,26 @@ IFACEMETHODIMP CPowerRenameRegEx::GetReplaceTerm(_Outptr_ PWSTR* replaceTerm)
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CPowerRenameRegEx::_OnEnumerateItemsChanged()
|
||||
{
|
||||
m_enumerators.clear();
|
||||
const auto options = parseEnumOptions(m_RawReplaceTerm);
|
||||
for (const auto e : options)
|
||||
m_enumerators.emplace_back(e);
|
||||
|
||||
m_replaceWithEnumeratorOffsets.clear();
|
||||
std::wstring replaceWith{ m_RawReplaceTerm };
|
||||
// Remove counter expressions and calculate their offsets in replaceWith string.
|
||||
int32_t offset = 0;
|
||||
for (const auto& e : options)
|
||||
{
|
||||
replaceWith.erase(e.replaceStrSpan.offset + offset, e.replaceStrSpan.length);
|
||||
m_replaceWithEnumeratorOffsets.push_back(offset);
|
||||
offset -= static_cast<int32_t>(e.replaceStrSpan.length);
|
||||
}
|
||||
return SHStrDup(replaceWith.data(), &m_replaceTerm);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP CPowerRenameRegEx::PutReplaceTerm(_In_ PCWSTR replaceTerm, bool forceRenaming)
|
||||
{
|
||||
bool changed = false || forceRenaming;
|
||||
@@ -134,10 +157,15 @@ IFACEMETHODIMP CPowerRenameRegEx::PutReplaceTerm(_In_ PCWSTR replaceTerm, bool f
|
||||
if (replaceTerm)
|
||||
{
|
||||
CSRWExclusiveAutoLock lock(&m_lock);
|
||||
if (m_replaceTerm == nullptr || lstrcmp(replaceTerm, m_replaceTerm) != 0)
|
||||
if (m_replaceTerm == nullptr || lstrcmp(replaceTerm, m_RawReplaceTerm.c_str()) != 0)
|
||||
{
|
||||
changed = true;
|
||||
CoTaskMemFree(m_replaceTerm);
|
||||
m_RawReplaceTerm = replaceTerm;
|
||||
|
||||
if (m_flags & EnumerateItems)
|
||||
hr = _OnEnumerateItemsChanged();
|
||||
else
|
||||
hr = SHStrDup(replaceTerm, &m_replaceTerm);
|
||||
}
|
||||
}
|
||||
@@ -160,7 +188,20 @@ IFACEMETHODIMP CPowerRenameRegEx::PutFlags(_In_ DWORD flags)
|
||||
{
|
||||
if (m_flags != flags)
|
||||
{
|
||||
const bool newEnumerate = flags & EnumerateItems;
|
||||
const bool refreshReplaceTerm = !!(m_flags & EnumerateItems) != newEnumerate;
|
||||
m_flags = flags;
|
||||
if (refreshReplaceTerm)
|
||||
{
|
||||
CSRWExclusiveAutoLock lock(&m_lock);
|
||||
if (newEnumerate)
|
||||
_OnEnumerateItemsChanged();
|
||||
else
|
||||
{
|
||||
CoTaskMemFree(m_replaceTerm);
|
||||
SHStrDup(m_RawReplaceTerm.c_str(), &m_replaceTerm);
|
||||
}
|
||||
}
|
||||
_OnFlagsChanged();
|
||||
}
|
||||
return S_OK;
|
||||
@@ -202,7 +243,7 @@ HRESULT CPowerRenameRegEx::s_CreateInstance(_Outptr_ IPowerRenameRegEx** renameR
|
||||
{
|
||||
*renameRegEx = nullptr;
|
||||
|
||||
CPowerRenameRegEx *newRenameRegEx = new CPowerRenameRegEx();
|
||||
CPowerRenameRegEx* newRenameRegEx = new CPowerRenameRegEx();
|
||||
HRESULT hr = E_OUTOFMEMORY;
|
||||
if (newRenameRegEx)
|
||||
{
|
||||
@@ -228,7 +269,20 @@ CPowerRenameRegEx::~CPowerRenameRegEx()
|
||||
CoTaskMemFree(m_replaceTerm);
|
||||
}
|
||||
|
||||
HRESULT CPowerRenameRegEx::Replace(_In_ PCWSTR source, _Outptr_ PWSTR* result)
|
||||
template<bool Std, class Regex = conditional_t<Std, std::wregex, boost::wregex>, class Options = decltype(Regex::icase)>
|
||||
static std::wstring RegexReplaceEx(const std::wstring& source, const std::wstring& searchTerm, const std::wstring& replaceTerm, const bool matchAll, const bool caseInsensitive)
|
||||
{
|
||||
Regex pattern(searchTerm, Options::ECMAScript | (caseInsensitive ? Options::icase : Options{}));
|
||||
|
||||
using Flags = conditional_t<Std, std::regex_constants::match_flag_type, boost::regex_constants::match_flags>;
|
||||
const auto flags = matchAll ? Flags::match_default : Flags::format_first_only;
|
||||
|
||||
return regex_replace(source, pattern, replaceTerm, flags);
|
||||
}
|
||||
|
||||
static constexpr std::array RegexReplaceDispatch = { RegexReplaceEx<true>, RegexReplaceEx<false> };
|
||||
|
||||
HRESULT CPowerRenameRegEx::Replace(_In_ PCWSTR source, _Outptr_ PWSTR* result, unsigned long& enumIndex)
|
||||
{
|
||||
*result = nullptr;
|
||||
|
||||
@@ -238,7 +292,7 @@ HRESULT CPowerRenameRegEx::Replace(_In_ PCWSTR source, _Outptr_ PWSTR* result)
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
wstring res = source;
|
||||
std::wstring res = source;
|
||||
try
|
||||
{
|
||||
// TODO: creating the regex could be costly. May want to cache this.
|
||||
@@ -250,47 +304,49 @@ HRESULT CPowerRenameRegEx::Replace(_In_ PCWSTR source, _Outptr_ PWSTR* result)
|
||||
fileTimeErrorOccurred = true;
|
||||
}
|
||||
|
||||
std::wstring sourceToUse(source);
|
||||
std::wstring sourceToUse;
|
||||
std::wstring originalSource;
|
||||
sourceToUse.reserve(MAX_PATH);
|
||||
originalSource.reserve(MAX_PATH);
|
||||
sourceToUse = source;
|
||||
originalSource = sourceToUse;
|
||||
|
||||
std::wstring searchTerm(m_searchTerm);
|
||||
std::wstring replaceTerm(L"");
|
||||
std::wstring replaceTerm;
|
||||
if (m_useFileTime && !fileTimeErrorOccurred)
|
||||
{
|
||||
replaceTerm = wstring(newReplaceTerm);
|
||||
replaceTerm = newReplaceTerm;
|
||||
}
|
||||
else if (m_replaceTerm)
|
||||
{
|
||||
replaceTerm = wstring(m_replaceTerm);
|
||||
replaceTerm = m_replaceTerm;
|
||||
}
|
||||
|
||||
replaceTerm = regex_replace(replaceTerm, std::wregex(L"(([^\\$]|^)(\\$\\$)*)\\$[0]"), L"$1$$$0");
|
||||
replaceTerm = regex_replace(replaceTerm, std::wregex(L"(([^\\$]|^)(\\$\\$)*)\\$([1-9])"), L"$1$0$4");
|
||||
static const std::wregex zeroGroupRegex(L"(([^\\$]|^)(\\$\\$)*)\\$[0]");
|
||||
static const std::wregex otherGroupsRegex(L"(([^\\$]|^)(\\$\\$)*)\\$([1-9])");
|
||||
|
||||
if (m_flags & EnumerateItems)
|
||||
{
|
||||
std::array<wchar_t, MAX_PATH> buffer;
|
||||
int32_t offset = 0;
|
||||
|
||||
for (size_t ei = 0; ei < m_enumerators.size(); ++ei)
|
||||
{
|
||||
const auto& e = m_enumerators[ei];
|
||||
const auto replacementLength = static_cast<int32_t>(e.printTo(buffer.data(), buffer.size(), enumIndex));
|
||||
replaceTerm.insert(e.replaceStrSpan.offset + offset + m_replaceWithEnumeratorOffsets[ei], buffer.data());
|
||||
offset += replacementLength;
|
||||
}
|
||||
}
|
||||
|
||||
bool replacedSomething = false;
|
||||
if (m_flags & UseRegularExpressions)
|
||||
{
|
||||
if (_useBoostLib)
|
||||
{
|
||||
boost::wregex pattern(m_searchTerm, (!(m_flags & CaseSensitive)) ? boost::regex::icase | boost::regex::ECMAScript : boost::regex::ECMAScript);
|
||||
if (m_flags & MatchAllOccurrences)
|
||||
{
|
||||
res = boost::regex_replace(wstring(source), pattern, replaceTerm);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = boost::regex_replace(wstring(source), pattern, replaceTerm, boost::regex_constants::format_first_only);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wregex pattern(m_searchTerm, (!(m_flags & CaseSensitive)) ? regex_constants::icase | regex_constants::ECMAScript : regex_constants::ECMAScript);
|
||||
if (m_flags & MatchAllOccurrences)
|
||||
{
|
||||
res = regex_replace(wstring(source), pattern, replaceTerm);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = regex_replace(wstring(source), pattern, replaceTerm, regex_constants::format_first_only);
|
||||
}
|
||||
}
|
||||
replaceTerm = regex_replace(replaceTerm, zeroGroupRegex, L"$1$$$0");
|
||||
replaceTerm = regex_replace(replaceTerm, otherGroupsRegex, L"$1$0$4");
|
||||
|
||||
res = RegexReplaceDispatch[_useBoostLib](source, m_searchTerm, replaceTerm, m_flags & MatchAllOccurrences, !(m_flags & CaseSensitive));
|
||||
replacedSomething = originalSource != res;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -303,16 +359,17 @@ HRESULT CPowerRenameRegEx::Replace(_In_ PCWSTR source, _Outptr_ PWSTR* result)
|
||||
{
|
||||
res = sourceToUse.replace(pos, searchTerm.length(), replaceTerm);
|
||||
pos += replaceTerm.length();
|
||||
replacedSomething = true;
|
||||
}
|
||||
|
||||
if (!(m_flags & MatchAllOccurrences))
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (pos != std::string::npos);
|
||||
}
|
||||
|
||||
hr = SHStrDup(res.c_str(), result);
|
||||
if (replacedSomething)
|
||||
enumIndex++;
|
||||
}
|
||||
catch (regex_error e)
|
||||
{
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
#include "pch.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "srwlock.h"
|
||||
|
||||
#include "Enumerating.h"
|
||||
#include "PowerRenameInterfaces.h"
|
||||
|
||||
#define DEFAULT_FLAGS 0
|
||||
@@ -27,9 +26,9 @@ public:
|
||||
IFACEMETHODIMP PutFlags(_In_ DWORD flags);
|
||||
IFACEMETHODIMP PutFileTime(_In_ SYSTEMTIME fileTime);
|
||||
IFACEMETHODIMP ResetFileTime();
|
||||
IFACEMETHODIMP Replace(_In_ PCWSTR source, _Outptr_ PWSTR* result);
|
||||
IFACEMETHODIMP Replace(_In_ PCWSTR source, _Outptr_ PWSTR* result, unsigned long& enumIndex);
|
||||
|
||||
static HRESULT s_CreateInstance(_Outptr_ IPowerRenameRegEx **renameRegEx);
|
||||
static HRESULT s_CreateInstance(_Outptr_ IPowerRenameRegEx** renameRegEx);
|
||||
|
||||
protected:
|
||||
CPowerRenameRegEx();
|
||||
@@ -39,6 +38,7 @@ protected:
|
||||
void _OnReplaceTermChanged();
|
||||
void _OnFlagsChanged();
|
||||
void _OnFileTimeChanged();
|
||||
HRESULT _OnEnumerateItemsChanged();
|
||||
|
||||
size_t _Find(std::wstring data, std::wstring toSearch, bool caseInsensitive, size_t pos);
|
||||
|
||||
@@ -46,8 +46,9 @@ protected:
|
||||
DWORD m_flags = DEFAULT_FLAGS;
|
||||
PWSTR m_searchTerm = nullptr;
|
||||
PWSTR m_replaceTerm = nullptr;
|
||||
std::wstring m_RawReplaceTerm;
|
||||
|
||||
SYSTEMTIME m_fileTime = {0};
|
||||
SYSTEMTIME m_fileTime = { 0 };
|
||||
bool m_useFileTime = false;
|
||||
|
||||
CSRWLock m_lock;
|
||||
@@ -55,6 +56,9 @@ protected:
|
||||
|
||||
DWORD m_cookie = 0;
|
||||
|
||||
std::vector<Enumerator> m_enumerators;
|
||||
std::vector<int32_t> m_replaceWithEnumeratorOffsets;
|
||||
|
||||
struct RENAME_REGEX_EVENT
|
||||
{
|
||||
IPowerRenameRegExEvents* pEvents;
|
||||
|
||||
@@ -86,7 +86,7 @@ bool DoRename(CComPtr<IPowerRenameRegEx>& spRenameRegEx, unsigned long& itemEnum
|
||||
|
||||
// Failure here means we didn't match anything or had nothing to match
|
||||
// Call put_newName with null in that case to reset it
|
||||
winrt::check_hresult(spRenameRegEx->Replace(sourceName, &newName));
|
||||
winrt::check_hresult(spRenameRegEx->Replace(sourceName, &newName, itemEnumIndex));
|
||||
|
||||
if (useFileTime)
|
||||
{
|
||||
@@ -166,17 +166,6 @@ bool DoRename(CComPtr<IPowerRenameRegEx>& spRenameRegEx, unsigned long& itemEnum
|
||||
newNameToUse = nullptr;
|
||||
}
|
||||
|
||||
wchar_t uniqueName[MAX_PATH] = { 0 };
|
||||
if (newNameToUse != nullptr && (flags & EnumerateItems))
|
||||
{
|
||||
unsigned long countUsed = 0;
|
||||
if (GetEnumeratedFileName(uniqueName, ARRAYSIZE(uniqueName), newNameToUse, nullptr, itemEnumIndex, &countUsed))
|
||||
{
|
||||
newNameToUse = uniqueName;
|
||||
}
|
||||
itemEnumIndex++;
|
||||
}
|
||||
|
||||
spItem->PutStatus(PowerRenameItemRenameStatus::ShouldRename);
|
||||
if (newNameToUse != nullptr)
|
||||
{
|
||||
|
||||
@@ -21,6 +21,12 @@
|
||||
#include <shlwapi.h>
|
||||
#include <ShlObj_core.h>
|
||||
#include <filesystem>
|
||||
#include <compare>
|
||||
#include <regex>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
#include <charconv>
|
||||
#include <string>
|
||||
|
||||
#include <ProjectTelemetry.h>
|
||||
|
||||
|
||||
472
src/modules/powerrename/unittests/CommonRegExTests.h
Normal file
472
src/modules/powerrename/unittests/CommonRegExTests.h
Normal file
@@ -0,0 +1,472 @@
|
||||
//#undef TESTS_PARTIAL // Uncomment temporarily to make intellisense work in this file.
|
||||
#ifndef TESTS_PARTIAL
|
||||
#include "CppUnitTestInclude.h"
|
||||
#include "powerrename/lib/Settings.h"
|
||||
#include <PowerRenameInterfaces.h>
|
||||
#include <PowerRenameRegEx.h>
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
namespace PowerRenameRegExTests
|
||||
{
|
||||
TEST_CLASS (SimpleTests)
|
||||
{
|
||||
public:
|
||||
#endif
|
||||
|
||||
struct SearchReplaceExpected
|
||||
{
|
||||
PCWSTR search;
|
||||
PCWSTR replace;
|
||||
PCWSTR test;
|
||||
PCWSTR expected;
|
||||
};
|
||||
|
||||
TEST_METHOD (GeneralReplaceTest)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"foo") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"big") == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::AreEqual(L"bigbar", result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD (ReplaceNoMatch)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"notfound") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"big") == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::AreEqual(L"foobar", result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD (ReplaceNoSearchOrReplaceTerm)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::IsTrue(result == nullptr);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD (ReplaceNoReplaceTerm)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"foo") == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::AreEqual(L"bar", result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD (ReplaceEmptyStringReplaceTerm)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"foo") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"") == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::AreEqual(L"bar", result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyDefaultFlags)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = 0;
|
||||
Assert::IsTrue(renameRegEx->GetFlags(&flags) == S_OK);
|
||||
Assert::IsTrue(flags == 0);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyCaseSensitiveSearch)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = CaseSensitive;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"Foo", L"Foo", L"FooBar", L"FooBar" },
|
||||
{ L"Foo", L"boo", L"FooBar", L"booBar" },
|
||||
{ L"Foo", L"boo", L"foobar", L"foobar" },
|
||||
{ L"123", L"654", L"123456", L"654456" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyReplaceFirstOnly)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = 0;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AABBA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABAB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyReplaceAll)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AAAAA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABBBABBB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyReplaceAllCaseInsensitive)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences | CaseSensitive;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AAAAA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABBBABBB" },
|
||||
{ L"b", L"BBB", L"AbABAb", L"ABBBABABBB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyReplaceFirstOnlyUseRegEx)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = UseRegularExpressions;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AABBA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABAB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyReplaceAllUseRegEx)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences | UseRegularExpressions;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AAAAA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABBBABBB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyReplaceAllUseRegExCaseSensitive)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences | UseRegularExpressions | CaseSensitive;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AAAAA" },
|
||||
{ L"b", L"BBB", L"AbABAb", L"ABBBABABBB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
void VerifyReplaceFirstWildcard(SearchReplaceExpected sreTable[], int tableSize, DWORD flags)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
for (int i = 0; i < tableSize; i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::AreEqual(sreTable[i].expected, result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyReplaceFirstWildCardUseRegex)
|
||||
{
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
//search, replace, test, result
|
||||
{ L".*", L"Foo", L"AAAAAA", L"Foo" },
|
||||
};
|
||||
VerifyReplaceFirstWildcard(sreTable, ARRAYSIZE(sreTable), UseRegularExpressions);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyReplaceFirstWildCardMatchAllOccurrences)
|
||||
{
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
//search, replace, test, result
|
||||
{ L".*", L"Foo", L"AAAAAA", L"AAAAAA" },
|
||||
{ L".*", L"Foo", L".*", L"Foo" },
|
||||
{ L".*", L"Foo", L".*Bar.*", L"FooBarFoo" },
|
||||
};
|
||||
VerifyReplaceFirstWildcard(sreTable, ARRAYSIZE(sreTable), MatchAllOccurrences);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyReplaceFirstWildNoFlags)
|
||||
{
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
//search, replace, test, result
|
||||
{ L".*", L"Foo", L"AAAAAA", L"AAAAAA" },
|
||||
{ L".*", L"Foo", L".*", L"Foo" },
|
||||
};
|
||||
VerifyReplaceFirstWildcard(sreTable, ARRAYSIZE(sreTable), 0);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyEventsFire)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
CMockPowerRenameRegExEvents* mockEvents = new CMockPowerRenameRegExEvents();
|
||||
CComPtr<IPowerRenameRegExEvents> regExEvents;
|
||||
Assert::IsTrue(mockEvents->QueryInterface(IID_PPV_ARGS(®ExEvents)) == S_OK);
|
||||
DWORD cookie = 0;
|
||||
Assert::IsTrue(renameRegEx->Advise(regExEvents, &cookie) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences | UseRegularExpressions | CaseSensitive;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"FOO") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"BAR") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutFileTime(SYSTEMTIME{ 0 }) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->ResetFileTime() == S_OK);
|
||||
Assert::IsTrue(lstrcmpi(L"FOO", mockEvents->m_searchTerm) == 0);
|
||||
Assert::IsTrue(lstrcmpi(L"BAR", mockEvents->m_replaceTerm) == 0);
|
||||
Assert::IsTrue(flags == mockEvents->m_flags);
|
||||
Assert::IsTrue(renameRegEx->UnAdvise(cookie) == S_OK);
|
||||
mockEvents->Release();
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifySimpleCounterNoRegex)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = EnumerateItems;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"bar") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"$1bar_${}") == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::AreEqual(L"foo$1bar_0", result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifySimpleCounterNoEnum)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = UseRegularExpressions;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"bar") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"$1bar_${}") == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::AreEqual(L"foobar_${}", result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifySimpleCounter)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = EnumerateItems | UseRegularExpressions;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"bar") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"bar_${}") == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::AreEqual(L"foobar_0", result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyMultipleCounters)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = EnumerateItems | UseRegularExpressions;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"bar") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"_${}_bar_${}") == S_OK);
|
||||
unsigned long index = {};
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::AreEqual(L"foo_0_bar_0", result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyCounterIncrementCustomization)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = EnumerateItems | UseRegularExpressions;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"bar") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"bar_${increment=10}") == S_OK);
|
||||
unsigned long index = 1;
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::AreEqual(L"foobar_10", result);
|
||||
Assert::AreEqual<unsigned long>(index, 2);
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::AreEqual(L"foobar_20", result);
|
||||
Assert::AreEqual<unsigned long>(index, 3);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyCounterStartCustomization)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = EnumerateItems | UseRegularExpressions;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"bar") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"bar_${start=1000}") == S_OK);
|
||||
unsigned long index = 5;
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::AreEqual(L"foobar_1005", result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyCounterPaddingCustomization)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = EnumerateItems | UseRegularExpressions;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"bar") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"bar_${padding=5}") == S_OK);
|
||||
unsigned long index = 204;
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::AreEqual(L"foobar_00204", result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD (VerifyCounterAllCustomizations)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = EnumerateItems | UseRegularExpressions;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"bar") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"bar_${increment=7,start=993,padding=5}") == S_OK);
|
||||
unsigned long index = 12;
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result, index) == S_OK);
|
||||
Assert::AreEqual(L"foobar_01077", result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
#ifndef TESTS_PARTIAL
|
||||
};
|
||||
}
|
||||
#endif
|
||||
8
src/modules/powerrename/unittests/CppUnitTestInclude.h
Normal file
8
src/modules/powerrename/unittests/CppUnitTestInclude.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
// Headers for CppUnitTest
|
||||
|
||||
// Suppressing 26466 - Don't use static_cast downcasts - in CppUnitTest.h
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 26466)
|
||||
#include "CppUnitTest.h"
|
||||
#pragma warning(pop)
|
||||
@@ -38,6 +38,7 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CppUnitTestInclude.h" />
|
||||
<ClInclude Include="MockPowerRenameItem.h" />
|
||||
<ClInclude Include="MockPowerRenameManagerEvents.h" />
|
||||
<ClInclude Include="MockPowerRenameRegExEvents.h" />
|
||||
@@ -45,6 +46,7 @@
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="TestFileHelper.h" />
|
||||
<ClInclude Include="CommonRegExTests.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="MockPowerRenameItem.cpp" />
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="TestFileHelper.h" />
|
||||
<ClInclude Include="CommonRegExTests.h" />
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CppUnitTestInclude.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Resource Files">
|
||||
|
||||
@@ -8,14 +8,6 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace PowerRenameRegExBoostTests
|
||||
{
|
||||
struct SearchReplaceExpected
|
||||
{
|
||||
PCWSTR search;
|
||||
PCWSTR replace;
|
||||
PCWSTR test;
|
||||
PCWSTR expected;
|
||||
};
|
||||
|
||||
TEST_CLASS(SimpleTests)
|
||||
{
|
||||
public:
|
||||
@@ -29,241 +21,8 @@ TEST_CLASS_CLEANUP(ClassCleanup)
|
||||
CSettingsInstance().SetUseBoostLib(false);
|
||||
}
|
||||
|
||||
TEST_METHOD(GeneralReplaceTest)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"foo") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"big") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, L"bigbar") == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD(ReplaceNoMatch)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"notfound") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"big") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, L"foobar") == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD(ReplaceNoSearchOrReplaceTerm)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result) == S_OK);
|
||||
Assert::IsTrue(result == nullptr);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD(ReplaceNoReplaceTerm)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"foo") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, L"bar") == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD(ReplaceEmptyStringReplaceTerm)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"foo") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, L"bar") == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyDefaultFlags)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = 0;
|
||||
Assert::IsTrue(renameRegEx->GetFlags(&flags) == S_OK);
|
||||
Assert::IsTrue(flags == 0);
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyCaseSensitiveSearch)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = CaseSensitive;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"Foo", L"Foo", L"FooBar", L"FooBar" },
|
||||
{ L"Foo", L"boo", L"FooBar", L"booBar" },
|
||||
{ L"Foo", L"boo", L"foobar", L"foobar" },
|
||||
{ L"123", L"654", L"123456", L"654456" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceFirstOnly)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = 0;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AABBA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABAB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceAll)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AAAAA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABBBABBB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceAllCaseInsensitive)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences | CaseSensitive;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AAAAA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABBBABBB" },
|
||||
{ L"b", L"BBB", L"AbABAb", L"ABBBABABBB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceFirstOnlyUseRegEx)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = UseRegularExpressions;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AABBA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABAB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceAllUseRegEx)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences | UseRegularExpressions;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AAAAA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABBBABBB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceAllUseRegExCaseSensitive)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences | UseRegularExpressions | CaseSensitive;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AAAAA" },
|
||||
{ L"b", L"BBB", L"AbABAb", L"ABBBABABBB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
#define TESTS_PARTIAL
|
||||
#include "CommonRegExTests.h"
|
||||
|
||||
TEST_METHOD(VerifyMatchAllWildcardUseRegEx)
|
||||
{
|
||||
@@ -284,38 +43,13 @@ TEST_METHOD(VerifyMatchAllWildcardUseRegEx)
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
void VerifyReplaceFirstWildcard(SearchReplaceExpected sreTable[], int tableSize, DWORD flags)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
for (int i = 0; i < tableSize; i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::AreEqual(sreTable[i].expected, result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceFirstWildCardUseRegex)
|
||||
{
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
//search, replace, test, result
|
||||
{ L".*", L"Foo", L"AAAAAA", L"Foo" },
|
||||
};
|
||||
VerifyReplaceFirstWildcard(sreTable, ARRAYSIZE(sreTable), UseRegularExpressions);
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceFirstWildCardUseRegexMatchAllOccurrences)
|
||||
{
|
||||
// This differs from the Standard Library: .* has two matches (all and nothing).
|
||||
@@ -327,27 +61,6 @@ TEST_METHOD(VerifyReplaceFirstWildCardUseRegexMatchAllOccurrences)
|
||||
VerifyReplaceFirstWildcard(sreTable, ARRAYSIZE(sreTable), UseRegularExpressions | MatchAllOccurrences);
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceFirstWildCardMatchAllOccurrences)
|
||||
{
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
//search, replace, test, result
|
||||
{ L".*", L"Foo", L"AAAAAA", L"AAAAAA" },
|
||||
{ L".*", L"Foo", L".*", L"Foo" },
|
||||
{ L".*", L"Foo", L".*Bar.*", L"FooBarFoo" },
|
||||
};
|
||||
VerifyReplaceFirstWildcard(sreTable, ARRAYSIZE(sreTable), MatchAllOccurrences);
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceFirstWildNoFlags)
|
||||
{
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
//search, replace, test, result
|
||||
{ L".*", L"Foo", L"AAAAAA", L"AAAAAA" },
|
||||
{ L".*", L"Foo", L".*", L"Foo" },
|
||||
};
|
||||
VerifyReplaceFirstWildcard(sreTable, ARRAYSIZE(sreTable), 0);
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyHandleCapturingGroups)
|
||||
{
|
||||
// This differs from the Standard Library: Boost does not recognize $123 as $1 and "23".
|
||||
@@ -380,7 +93,8 @@ TEST_METHOD(VerifyHandleCapturingGroups)
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
@@ -407,32 +121,11 @@ TEST_METHOD(VerifyLookbehind)
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyEventsFire)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
CMockPowerRenameRegExEvents* mockEvents = new CMockPowerRenameRegExEvents();
|
||||
CComPtr<IPowerRenameRegExEvents> regExEvents;
|
||||
Assert::IsTrue(mockEvents->QueryInterface(IID_PPV_ARGS(®ExEvents)) == S_OK);
|
||||
DWORD cookie = 0;
|
||||
Assert::IsTrue(renameRegEx->Advise(regExEvents, &cookie) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences | UseRegularExpressions | CaseSensitive;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"FOO") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"BAR") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutFileTime(SYSTEMTIME{0}) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->ResetFileTime() == S_OK);
|
||||
Assert::IsTrue(lstrcmpi(L"FOO", mockEvents->m_searchTerm) == 0);
|
||||
Assert::IsTrue(lstrcmpi(L"BAR", mockEvents->m_replaceTerm) == 0);
|
||||
Assert::IsTrue(flags == mockEvents->m_flags);
|
||||
Assert::IsTrue(renameRegEx->UnAdvise(cookie) == S_OK);
|
||||
mockEvents->Release();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,14 +8,6 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace PowerRenameRegExTests
|
||||
{
|
||||
struct SearchReplaceExpected
|
||||
{
|
||||
PCWSTR search;
|
||||
PCWSTR replace;
|
||||
PCWSTR test;
|
||||
PCWSTR expected;
|
||||
};
|
||||
|
||||
TEST_CLASS(SimpleTests){
|
||||
public:
|
||||
TEST_CLASS_INITIALIZE(ClassInitialize)
|
||||
@@ -23,241 +15,8 @@ TEST_CLASS_INITIALIZE(ClassInitialize)
|
||||
CSettingsInstance().SetUseBoostLib(false);
|
||||
}
|
||||
|
||||
TEST_METHOD(GeneralReplaceTest)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"foo") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"big") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, L"bigbar") == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD(ReplaceNoMatch)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"notfound") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"big") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, L"foobar") == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD(ReplaceNoSearchOrReplaceTerm)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result) == S_OK);
|
||||
Assert::IsTrue(result == nullptr);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD(ReplaceNoReplaceTerm)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"foo") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, L"bar") == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD(ReplaceEmptyStringReplaceTerm)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"foo") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(L"foobar", &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, L"bar") == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyDefaultFlags)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = 0;
|
||||
Assert::IsTrue(renameRegEx->GetFlags(&flags) == S_OK);
|
||||
Assert::IsTrue(flags == 0);
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyCaseSensitiveSearch)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = CaseSensitive;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"Foo", L"Foo", L"FooBar", L"FooBar" },
|
||||
{ L"Foo", L"boo", L"FooBar", L"booBar" },
|
||||
{ L"Foo", L"boo", L"foobar", L"foobar" },
|
||||
{ L"123", L"654", L"123456", L"654456" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceFirstOnly)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = 0;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AABBA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABAB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceAll)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AAAAA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABBBABBB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceAllCaseInsensitive)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences | CaseSensitive;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AAAAA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABBBABBB" },
|
||||
{ L"b", L"BBB", L"AbABAb", L"ABBBABABBB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceFirstOnlyUseRegEx)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = UseRegularExpressions;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AABBA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABAB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceAllUseRegEx)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences | UseRegularExpressions;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AAAAA" },
|
||||
{ L"B", L"BBB", L"ABABAB", L"ABBBABBBABBB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceAllUseRegExCaseSensitive)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences | UseRegularExpressions | CaseSensitive;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
{ L"B", L"BB", L"ABA", L"ABBA" },
|
||||
{ L"B", L"A", L"ABBBA", L"AAAAA" },
|
||||
{ L"b", L"BBB", L"AbABAb", L"ABBBABABBB" },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(sreTable); i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
#define TESTS_PARTIAL
|
||||
#include "CommonRegExTests.h"
|
||||
|
||||
TEST_METHOD(VerifyMatchAllWildcardUseRegEx)
|
||||
{
|
||||
@@ -275,38 +34,13 @@ TEST_METHOD(VerifyMatchAllWildcardUseRegEx)
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
void VerifyReplaceFirstWildcard(SearchReplaceExpected sreTable[], int tableSize, DWORD flags)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
|
||||
for (int i = 0; i < tableSize; i++)
|
||||
{
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
Assert::AreEqual(sreTable[i].expected, result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceFirstWildCardUseRegex)
|
||||
{
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
//search, replace, test, result
|
||||
{ L".*", L"Foo", L"AAAAAA", L"Foo" },
|
||||
};
|
||||
VerifyReplaceFirstWildcard(sreTable, ARRAYSIZE(sreTable), UseRegularExpressions);
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceFirstWildCardUseRegexMatchAllOccurrences)
|
||||
{
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
@@ -316,27 +50,6 @@ TEST_METHOD(VerifyReplaceFirstWildCardUseRegexMatchAllOccurrences)
|
||||
VerifyReplaceFirstWildcard(sreTable, ARRAYSIZE(sreTable), UseRegularExpressions | MatchAllOccurrences);
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceFirstWildCardMatchAllOccurrences)
|
||||
{
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
//search, replace, test, result
|
||||
{ L".*", L"Foo", L"AAAAAA", L"AAAAAA" },
|
||||
{ L".*", L"Foo", L".*", L"Foo" },
|
||||
{ L".*", L"Foo", L".*Bar.*", L"FooBarFoo" },
|
||||
};
|
||||
VerifyReplaceFirstWildcard(sreTable, ARRAYSIZE(sreTable), MatchAllOccurrences);
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyReplaceFirstWildNoFlags)
|
||||
{
|
||||
SearchReplaceExpected sreTable[] = {
|
||||
//search, replace, test, result
|
||||
{ L".*", L"Foo", L"AAAAAA", L"AAAAAA" },
|
||||
{ L".*", L"Foo", L".*", L"Foo" },
|
||||
};
|
||||
VerifyReplaceFirstWildcard(sreTable, ARRAYSIZE(sreTable), 0);
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyHandleCapturingGroups)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
@@ -362,7 +75,8 @@ TEST_METHOD(VerifyHandleCapturingGroups)
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
@@ -387,7 +101,8 @@ TEST_METHOD (VerifyFileAttributesNoPadding)
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutFileTime(fileTime) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
@@ -411,7 +126,8 @@ TEST_METHOD (VerifyFileAttributesPadding)
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutFileTime(fileTime) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
@@ -459,7 +175,8 @@ TEST_METHOD (VerifyFileAttributesMonthandDayNames)
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutFileTime(fileTime) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == S_OK);
|
||||
Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
@@ -483,33 +200,12 @@ TEST_METHOD(VerifyLookbehindFails)
|
||||
PWSTR result = nullptr;
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(sreTable[i].search) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(sreTable[i].replace) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == E_FAIL);
|
||||
unsigned long index = {};
|
||||
Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result, index) == E_FAIL);
|
||||
Assert::AreEqual(sreTable[i].expected, result);
|
||||
CoTaskMemFree(result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyEventsFire)
|
||||
{
|
||||
CComPtr<IPowerRenameRegEx> renameRegEx;
|
||||
Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK);
|
||||
CMockPowerRenameRegExEvents* mockEvents = new CMockPowerRenameRegExEvents();
|
||||
CComPtr<IPowerRenameRegExEvents> regExEvents;
|
||||
Assert::IsTrue(mockEvents->QueryInterface(IID_PPV_ARGS(®ExEvents)) == S_OK);
|
||||
DWORD cookie = 0;
|
||||
Assert::IsTrue(renameRegEx->Advise(regExEvents, &cookie) == S_OK);
|
||||
DWORD flags = MatchAllOccurrences | UseRegularExpressions | CaseSensitive;
|
||||
Assert::IsTrue(renameRegEx->PutFlags(flags) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutSearchTerm(L"FOO") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutReplaceTerm(L"BAR") == S_OK);
|
||||
Assert::IsTrue(renameRegEx->PutFileTime(SYSTEMTIME{ 0 }) == S_OK);
|
||||
Assert::IsTrue(renameRegEx->ResetFileTime() == S_OK);
|
||||
Assert::IsTrue(lstrcmpi(L"FOO", mockEvents->m_searchTerm) == 0);
|
||||
Assert::IsTrue(lstrcmpi(L"BAR", mockEvents->m_replaceTerm) == 0);
|
||||
Assert::IsTrue(flags == mockEvents->m_flags);
|
||||
Assert::IsTrue(renameRegEx->UnAdvise(cookie) == S_OK);
|
||||
mockEvents->Release();
|
||||
}
|
||||
}
|
||||
;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,11 +3,4 @@
|
||||
#include "targetver.h"
|
||||
|
||||
#include <atlbase.h>
|
||||
|
||||
// Headers for CppUnitTest
|
||||
|
||||
// Suppressing 26466 - Don't use static_cast downcasts - in CppUnitTest.h
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 26466)
|
||||
#include "CppUnitTest.h"
|
||||
#pragma warning(pop)
|
||||
#include "CppUnitTestInclude.h"
|
||||
Reference in New Issue
Block a user