Skip to content

Commit

Permalink
text buffer tests
Browse files Browse the repository at this point in the history
  • Loading branch information
PankajBhojwani committed Aug 17, 2020
1 parent 4a74f83 commit 049ee61
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 7 deletions.
17 changes: 15 additions & 2 deletions src/buffer/out/textBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,6 @@ bool TextBuffer::IncrementCircularBuffer(const bool inVtMode)
if (it->IsHyperlink() && (refs.find(it->GetHyperlinkId()) != refs.end()))
{
refs.erase(it->GetHyperlinkId());
RemoveHyperlinkFromMap(it->GetHyperlinkId());
if (refs.empty())
{
// No more hyperlink references left to search for, terminate early
Expand All @@ -589,6 +588,11 @@ bool TextBuffer::IncrementCircularBuffer(const bool inVtMode)
}
}
end_outer_loop:
// Now delete obsolete references from our map
for (auto it = refs.begin(); it != refs.end(); ++it)
{
RemoveHyperlinkFromMap(*it);
}

// Second, clean out the old "first row" as it will become the "last row" of the buffer after the circle is performed.
auto fillAttributes = _currentAttributes;
Expand Down Expand Up @@ -2297,10 +2301,19 @@ USHORT TextBuffer::GetHyperlinkId(std::wstring_view params)
}

// Method Description:
// - Removes a hyperlink from the map
// - Removes a hyperlink from the hyperlink map and the associated
// user defined id from the custom id map (if there is one)
// Arguments:
// - The ID of the hyperlink to be removed
void TextBuffer::RemoveHyperlinkFromMap(USHORT id)
{
_hyperlinkMap.erase(id);
for (auto it = _customIdMap.begin(); it != _customIdMap.end(); ++it)
{
if (it->second == id)
{
_customIdMap.erase(it->first);
break;
}
}
}
79 changes: 79 additions & 0 deletions src/host/ut_host/TextBufferTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ class TextBufferTests

TEST_METHOD(GetTextRects);
TEST_METHOD(GetText);

TEST_METHOD(HyperlinkTrim);
TEST_METHOD(NoHyperlinkTrim);
};

void TextBufferTests::TestBufferCreate()
Expand Down Expand Up @@ -2443,3 +2446,79 @@ void TextBufferTests::GetText()
VERIFY_ARE_EQUAL(expectedText, result);
}
}

// This tests that when we increment the circular buffer, obsolete hyperlink references
// are removed from the hyperlink map
void TextBufferTests::HyperlinkTrim()
{
// Set up a text buffer for us
const COORD bufferSize{ 80, 10 };
const UINT cursorSize = 12;
const TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, _renderTarget);

const auto url = L"test.url";
const auto otherUrl = L"other.url";
const auto customId = L"CustomId";
const auto otherCustomId = L"OtherCustomId";

// Set a hyperlink id in the first row and add a hyperlink to our map
const COORD pos{ 70, 0 };
USHORT id = _buffer->GetHyperlinkId(customId);
TextAttribute newAttr{ 0x7f };
newAttr.SetHyperlinkId(id);
_buffer->GetRowByOffset(pos.Y).GetAttrRow().SetAttrToEnd(pos.X, newAttr);
_buffer->AddHyperlinkToMap(url, id);

// Set a different hyperlink id somewhere else in the buffer
const COORD otherPos{ 70, 5 };
USHORT otherId = _buffer->GetHyperlinkId(otherCustomId);
newAttr.SetHyperlinkId(otherId);
_buffer->GetRowByOffset(otherPos.Y).GetAttrRow().SetAttrToEnd(otherPos.X, newAttr);
_buffer->AddHyperlinkToMap(otherUrl, otherId);

// Increment the circular buffer
_buffer->IncrementCircularBuffer();

// The hyperlink reference that was only in the first row should be deleted from the map
VERIFY_ARE_EQUAL(_buffer->_hyperlinkMap.find(id), _buffer->_hyperlinkMap.end());
// Since there was a custom id, that should be deleted as well
VERIFY_ARE_EQUAL(_buffer->_customIdMap.find(customId), _buffer->_customIdMap.end());

// The other hyperlink reference should not be deleted
VERIFY_ARE_EQUAL(_buffer->_hyperlinkMap[otherId], otherUrl);
VERIFY_ARE_EQUAL(_buffer->_customIdMap[otherCustomId], otherId);
}

// This tests that when we increment the circular buffer, non-obsolete hyperlink references
// do not get removed from the hyperlink map
void TextBufferTests::NoHyperlinkTrim()
{
// Set up a text buffer for us
const COORD bufferSize{ 80, 10 };
const UINT cursorSize = 12;
const TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, _renderTarget);

const auto url = L"test.url";
const auto customId = L"CustomId";

// Set a hyperlink id in the first row and add a hyperlink to our map
const COORD pos{ 70, 0 };
USHORT id = _buffer->GetHyperlinkId(customId);
TextAttribute newAttr{ 0x7f };
newAttr.SetHyperlinkId(id);
_buffer->GetRowByOffset(pos.Y).GetAttrRow().SetAttrToEnd(pos.X, newAttr);
_buffer->AddHyperlinkToMap(url, id);

// Set the same hyperlink id somewhere else in the buffer
const COORD otherPos{ 70, 5 };
_buffer->GetRowByOffset(otherPos.Y).GetAttrRow().SetAttrToEnd(otherPos.X, newAttr);

// Increment the circular buffer
_buffer->IncrementCircularBuffer();

// The hyperlink reference should not be deleted from the map since it is still present in the buffer
VERIFY_ARE_EQUAL(_buffer->GetHyperlinkUriFromId(id), url);
VERIFY_ARE_EQUAL(_buffer->_customIdMap[customId], id);
}
2 changes: 1 addition & 1 deletion src/terminal/adapter/ut_adapter/adapterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ class TestGetSet final : public ConGetSet
}
}

bool PrivateAddHyperlink(const std::wstring_view /*uri*/) const
bool PrivateAddHyperlink(const std::wstring_view /*uri*/, const std::wstring_view /*params*/) const
{
Log::Comment(L"PrivateAddHyperlink MOCK called...");

Expand Down
8 changes: 4 additions & 4 deletions src/terminal/parser/OutputStateMachineEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1795,13 +1795,13 @@ bool OutputStateMachineEngine::_ParseHyperlink(const std::wstring_view string,
uri.clear();
const std::wstring idStr = L"id=";
const auto len = string.size();
const size_t midpos = string.find(';');
if (midpos != std::wstring::npos)
const size_t midPos = string.find(';');
if (midPos != std::wstring::npos)
{
if (len != 1)
{
uri = string.substr(midpos + 1);
const auto paramStr = string.substr(0, midpos);
uri = string.substr(midPos + 1);
const auto paramStr = string.substr(0, midPos);
const auto idPos = paramStr.find(idStr);
if (idPos != std::wstring::npos)
{
Expand Down

1 comment on commit 049ee61

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New misspellings found, please review:

  • wcstoui
To accept these changes, run the following commands
perl -e '
my @expect_files=qw('".github/actions/spell-check/expect/af1ff90dc512c83c902762b02f284c1c61603b4a.txt
.github/actions/spell-check/expect/alphabet.txt
.github/actions/spell-check/expect/expect.txt
.github/actions/spell-check/expect/web.txt"');
@ARGV=@expect_files;
my @stale=qw('"Autogenerated notypeopt "');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
  if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
  next if /^($re)(?:$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spell-check/expect/049ee61abb7eca206307d46f695c86181e04694a.txt";
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"autogenerated wcstoui "');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a) cmp lc($b)} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;'
git add .github/actions/spell-check/expect || echo '... you want to ensure .github/actions/spell-check/expect/049ee61abb7eca206307d46f695c86181e04694a.txt is added to your repository...'
✏️ Contributor please read this

By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.

⚠️ The command is written for posix shells. You can copy the contents of each perl command excluding the outer ' marks and dropping any '"/"' quotation mark pairs into a file and then run perl file.pl from the root of the repository to run the code. Alternatively, you can manually insert the items...

If the listed items are:

  • ... misspelled, then please correct them instead of using the command.
  • ... names, please add them to .github/actions/spell-check/dictionary/names.txt.
  • ... APIs, you can add them to a file in .github/actions/spell-check/dictionary/.
  • ... just things you're using, please add them to an appropriate file in .github/actions/spell-check/expect/.
  • ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in .github/actions/spell-check/patterns/.

See the README.md in each directory for more information.

🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The :check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉

⚠️ Reviewers

At present, the action that triggered this message will not show its ❌ in this PR unless the branch is within this repository.
Thus, you should make sure that this comment has been addressed before encouraging the merge bot to merge this PR.

Please sign in to comment.