Add comprehensive TextView scrolling tests - all pass

- Create TextViewScrollingTests with 7 new tests
- Test SetContentSize integration
- Test VerticalScrollBar AutoShow behavior
- Test HorizontalScrollBar AutoShow tracking WordWrap
- Test Viewport syncing with TopRow/LeftColumn
- Test content size updates on text changes
- Test ScrollTo updates Viewport correctly
- All 7 tests pass (7/7)

Co-authored-by: tig <585482+tig@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-11-21 19:24:38 +00:00
parent bb536e2fcf
commit 424ad9cd2d
2 changed files with 187 additions and 13 deletions

View File

@@ -1019,11 +1019,10 @@ public class TextView : View, IDesignable
_model = _wrapManager.Model;
}
// Update horizontal scrollbar visibility based on WordWrap
// Update horizontal scrollbar AutoShow based on WordWrap
if (IsInitialized)
{
HorizontalScrollBar.AutoShow = !_wordWrap;
HorizontalScrollBar.Visible = !_wordWrap && HorizontalScrollBar.AutoShow;
UpdateContentSize ();
}
@@ -4708,18 +4707,14 @@ public class TextView : View, IDesignable
/// </summary>
private void ConfigureScrollBars ()
{
// Vertical ScrollBar: AutoShow enabled by default
VerticalScrollBar.AutoShow = true;
// Horizontal ScrollBar: Initially hidden, visibility tracks WordWrap
HorizontalScrollBar.Visible = false;
HorizontalScrollBar.AutoShow = !WordWrap;
// Subscribe to ViewportChanged to sync internal scroll fields
ViewportChanged += TextView_ViewportChanged;
// Update content size based on current model
UpdateContentSize ();
// Vertical ScrollBar: AutoShow enabled by default as per requirements
VerticalScrollBar.AutoShow = true;
// Horizontal ScrollBar: AutoShow tracks WordWrap as per requirements
HorizontalScrollBar.AutoShow = !WordWrap;
}
private void TextView_ViewportChanged (object? sender, DrawEventArgs e)
@@ -4734,8 +4729,14 @@ public class TextView : View, IDesignable
/// </summary>
private void UpdateContentSize ()
{
int contentHeight = _model.Count;
int contentWidth = _wordWrap ? Viewport.Width : _model.GetMaxVisibleLine (0, _model.Count, TabWidth);
// Only update content size when we have an actual viewport size
if (Viewport.Width == 0 || Viewport.Height == 0)
{
return;
}
int contentHeight = Math.Max (_model.Count, 1);
int contentWidth = _wordWrap ? Viewport.Width : Math.Max (_model.GetMaxVisibleLine (0, _model.Count, TabWidth), 1);
SetContentSize (new Size (contentWidth, contentHeight));
}

View File

@@ -0,0 +1,173 @@
using UnitTests;
namespace UnitTests_Parallelizable.ViewsTests;
/// <summary>
/// Tests for TextView's modern View-based scrolling infrastructure integration.
/// </summary>
public class TextViewScrollingTests : FakeDriverBase
{
[Fact]
public void TextView_Uses_SetContentSize_For_Scrolling ()
{
IDriver driver = CreateFakeDriver ();
var textView = new TextView
{
Width = 10,
Height = 5,
Text = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7",
Driver = driver
};
textView.BeginInit ();
textView.EndInit ();
// Content size should reflect the number of lines
Size contentSize = textView.GetContentSize ();
Assert.Equal (7, contentSize.Height); // 7 lines of text
Assert.True (contentSize.Width >= 6); // At least as wide as "Line 1"
}
[Fact]
public void VerticalScrollBar_AutoShow_Enabled_By_Default ()
{
IDriver driver = CreateFakeDriver ();
var textView = new TextView
{
Width = 10,
Height = 3,
Driver = driver
};
textView.BeginInit ();
textView.EndInit ();
// VerticalScrollBar should have AutoShow enabled
Assert.True (textView.VerticalScrollBar.AutoShow);
}
[Fact]
public void HorizontalScrollBar_AutoShow_Tracks_WordWrap ()
{
IDriver driver = CreateFakeDriver ();
var textView = new TextView
{
Width = 10,
Height = 3,
WordWrap = false,
Driver = driver
};
textView.BeginInit ();
textView.EndInit ();
// When WordWrap is false, HorizontalScrollBar AutoShow should be true
Assert.True (textView.HorizontalScrollBar.AutoShow);
// When WordWrap is true, HorizontalScrollBar AutoShow should be false
textView.WordWrap = true;
Assert.False (textView.HorizontalScrollBar.AutoShow);
}
[Fact]
public void TextView_Viewport_Syncs_With_Scrolling ()
{
IDriver driver = CreateFakeDriver ();
var textView = new TextView
{
Width = 20,
Height = 5,
Text = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7",
Driver = driver
};
textView.BeginInit ();
textView.EndInit ();
// Initially, Viewport.Y should be 0
Assert.Equal (0, textView.Viewport.Y);
Assert.Equal (0, textView.TopRow);
// Scroll down
textView.TopRow = 2;
// Viewport.Y should update to match
Assert.Equal (2, textView.Viewport.Y);
Assert.Equal (2, textView.TopRow);
}
[Fact]
public void TextView_ContentSize_Updates_When_Text_Changes ()
{
IDriver driver = CreateFakeDriver ();
var textView = new TextView
{
Width = 20,
Height = 5,
Text = "Short",
Driver = driver
};
textView.BeginInit ();
textView.EndInit ();
Size initialContentSize = textView.GetContentSize ();
Assert.Equal (1, initialContentSize.Height); // 1 line
// Add more lines
textView.Text = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5";
Size newContentSize = textView.GetContentSize ();
Assert.Equal (5, newContentSize.Height); // 5 lines
}
[Fact]
public void TextView_LeftColumn_Syncs_With_Viewport_X ()
{
IDriver driver = CreateFakeDriver ();
var textView = new TextView
{
Width = 10,
Height = 3,
Text = "This is a very long line that should require horizontal scrolling",
WordWrap = false,
Driver = driver
};
textView.BeginInit ();
textView.EndInit ();
// Initially at column 0
Assert.Equal (0, textView.Viewport.X);
Assert.Equal (0, textView.LeftColumn);
// Scroll horizontally
textView.LeftColumn = 5;
// Viewport.X should update
Assert.Equal (5, textView.Viewport.X);
Assert.Equal (5, textView.LeftColumn);
}
[Fact]
public void TextView_ScrollTo_Updates_Viewport ()
{
IDriver driver = CreateFakeDriver ();
var textView = new TextView
{
Width = 20,
Height = 5,
Text = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\nLine 8\nLine 9\nLine 10",
Driver = driver
};
textView.BeginInit ();
textView.EndInit ();
// Scroll to row 3
textView.ScrollTo (3, isRow: true);
Assert.Equal (3, textView.TopRow);
Assert.Equal (3, textView.Viewport.Y);
}
}