Files
Terminal.Gui/UnitTests/Views/ScrollSliderTests.cs
2024-11-18 13:33:27 -07:00

1011 lines
26 KiB
C#

using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.TestPlatform.Utilities;
using Xunit.Abstractions;
using static Unix.Terminal.Delegates;
namespace Terminal.Gui.ViewsTests;
public class ScrollSliderTests (ITestOutputHelper output)
{
[Fact]
public void Constructor_Initializes_Correctly ()
{
var scrollSlider = new ScrollSlider ();
Assert.False (scrollSlider.CanFocus);
Assert.Equal (Orientation.Vertical, scrollSlider.Orientation);
Assert.Equal (TextDirection.TopBottom_LeftRight, scrollSlider.TextDirection);
Assert.Equal (Alignment.Center, scrollSlider.TextAlignment);
Assert.Equal (Alignment.Center, scrollSlider.VerticalTextAlignment);
scrollSlider.Layout ();
Assert.Equal (0, scrollSlider.Frame.X);
Assert.Equal (0, scrollSlider.Frame.Y);
Assert.Equal (1, scrollSlider.Size);
Assert.Equal (2048, scrollSlider.VisibleContentSize);
}
[Fact]
public void Add_To_SuperView_Initializes_Correctly ()
{
View super = new View ()
{
Id = "super",
Width = 10,
Height = 10,
CanFocus = true
};
var scrollSlider = new ScrollSlider ();
super.Add (scrollSlider);
Assert.False (scrollSlider.CanFocus);
Assert.Equal (Orientation.Vertical, scrollSlider.Orientation);
Assert.Equal (TextDirection.TopBottom_LeftRight, scrollSlider.TextDirection);
Assert.Equal (Alignment.Center, scrollSlider.TextAlignment);
Assert.Equal (Alignment.Center, scrollSlider.VerticalTextAlignment);
scrollSlider.Layout ();
Assert.Equal (0, scrollSlider.Frame.X);
Assert.Equal (0, scrollSlider.Frame.Y);
Assert.Equal (1, scrollSlider.Size);
Assert.Equal (10, scrollSlider.VisibleContentSize);
}
//[Fact]
//public void OnOrientationChanged_Sets_Size_To_1 ()
//{
// var scrollSlider = new ScrollSlider ();
// scrollSlider.Orientation = Orientation.Horizontal;
// Assert.Equal (1, scrollSlider.Size);
//}
[Fact]
public void OnOrientationChanged_Sets_Position_To_0 ()
{
View super = new View ()
{
Id = "super",
Width = 10,
Height = 10
};
var scrollSlider = new ScrollSlider ()
{
};
super.Add (scrollSlider);
scrollSlider.Layout ();
scrollSlider.Position = 1;
scrollSlider.Orientation = Orientation.Horizontal;
Assert.Equal (0, scrollSlider.Position);
}
[Fact]
public void OnOrientationChanged_Updates_TextDirection_And_TextAlignment ()
{
var scrollSlider = new ScrollSlider ();
scrollSlider.Orientation = Orientation.Horizontal;
Assert.Equal (TextDirection.LeftRight_TopBottom, scrollSlider.TextDirection);
Assert.Equal (Alignment.Center, scrollSlider.TextAlignment);
Assert.Equal (Alignment.Center, scrollSlider.VerticalTextAlignment);
}
[Theory]
[CombinatorialData]
public void Size_Clamps_To_SuperView_Viewport ([CombinatorialRange (-1, 6, 1)] int sliderSize, Orientation orientation)
{
var super = new View
{
Id = "super",
Width = 5,
Height = 5
};
var scrollSlider = new ScrollSlider
{
Orientation = orientation,
};
super.Add (scrollSlider);
scrollSlider.Layout ();
scrollSlider.Size = sliderSize;
scrollSlider.Layout ();
Assert.True (scrollSlider.Size > 0);
Assert.True (scrollSlider.Size <= 5);
}
[Theory]
[CombinatorialData]
public void Size_Clamps_To_VisibleContentSizes ([CombinatorialRange (1, 6, 1)] int dimension, [CombinatorialRange (-1, 6, 1)] int sliderSize, Orientation orientation)
{
var scrollSlider = new ScrollSlider
{
Orientation = orientation,
VisibleContentSize = dimension,
Size = sliderSize,
};
scrollSlider.Layout ();
Assert.True (scrollSlider.Size > 0);
Assert.True (scrollSlider.Size <= dimension);
}
[Theory]
[CombinatorialData]
public void CalculateSize_ScrollBounds_0_Returns_1 ([CombinatorialRange (-1, 5, 1)] int visibleContentSize, [CombinatorialRange (-1, 5, 1)] int scrollableContentSize)
{
// Arrange
// Act
var sliderSize = ScrollSlider.CalculateSize (scrollableContentSize, visibleContentSize, 0);
// Assert
Assert.Equal (1, sliderSize);
}
[Theory]
[CombinatorialData]
public void CalculateSize_ScrollableContentSize_0_Returns_1 ([CombinatorialRange (-1, 5, 1)] int visibleContentSize, [CombinatorialRange (-1, 5, 1)] int sliderBounds)
{
// Arrange
// Act
var sliderSize = ScrollSlider.CalculateSize (0, visibleContentSize, sliderBounds);
// Assert
Assert.Equal (1, sliderSize);
}
//[Theory]
//[CombinatorialData]
//public void CalculateSize_VisibleContentSize_0_Returns_0 ([CombinatorialRange (-1, 5, 1)] int scrollableContentSize, [CombinatorialRange (-1, 5, 1)] int sliderBounds)
//{
// // Arrange
// // Act
// var sliderSize = ScrollSlider.CalculateSize (scrollableContentSize, 0, sliderBounds);
// // Assert
// Assert.Equal (0, sliderSize);
//}
[Theory]
[InlineData (0, 1, 1, 1)]
[InlineData (1, 1, 1, 1)]
[InlineData (1, 2, 1, 1)]
[InlineData (0, 5, 5, 5)]
[InlineData (1, 5, 5, 1)]
[InlineData (2, 5, 5, 2)]
[InlineData (3, 5, 5, 3)]
[InlineData (4, 5, 5, 4)]
[InlineData (5, 5, 5, 5)]
[InlineData (6, 5, 5, 5)]
public void CalculateSize_Calculates_Correctly (int visibleContentSize, int scrollableContentSize, int scrollBounds, int expectedSliderSize)
{
// Arrange
// Act
var sliderSize = ScrollSlider.CalculateSize (scrollableContentSize, visibleContentSize, scrollBounds);
// Assert
Assert.Equal (expectedSliderSize, sliderSize);
}
[Fact]
public void VisibleContentSize_Not_Set_Uses_SuperView ()
{
View super = new ()
{
Id = "super",
Height = 5,
Width = 5,
};
var scrollSlider = new ScrollSlider
{
};
super.Add (scrollSlider);
super.Layout ();
Assert.Equal (5, scrollSlider.VisibleContentSize);
}
[Fact]
public void VisibleContentSize_Set_Overrides_SuperView ()
{
View super = new ()
{
Id = "super",
Height = 5,
Width = 5,
};
var scrollSlider = new ScrollSlider
{
VisibleContentSize = 10,
};
super.Add (scrollSlider);
super.Layout ();
Assert.Equal (10, scrollSlider.VisibleContentSize);
super.Height = 3;
super.Layout ();
Assert.Equal (10, scrollSlider.VisibleContentSize);
super.Height = 7;
super.Layout ();
Assert.Equal (10, scrollSlider.VisibleContentSize);
}
[Theory]
[CombinatorialData]
public void VisibleContentSizes_Clamps_0_To_Dimension ([CombinatorialRange (0, 10, 1)] int dimension, Orientation orientation)
{
var scrollSlider = new ScrollSlider
{
Orientation = orientation,
VisibleContentSize = dimension,
};
Assert.InRange (scrollSlider.VisibleContentSize, 1, 10);
View super = new ()
{
Id = "super",
Height = dimension,
Width = dimension,
};
scrollSlider = new ScrollSlider
{
Orientation = orientation,
};
super.Add (scrollSlider);
super.Layout ();
Assert.InRange (scrollSlider.VisibleContentSize, 1, 10);
scrollSlider.VisibleContentSize = dimension;
Assert.InRange (scrollSlider.VisibleContentSize, 1, 10);
}
[Theory]
//// 0123456789
//// ---------
//// ◄█►
//[InlineData (3, 3, 0, 1, 0)]
//[InlineData (3, 3, 1, 1, 0)]
//[InlineData (3, 3, 2, 1, 0)]
//// 0123456789
//// ---------
//// ◄██►
//[InlineData (4, 4, 0, 2, 0)]
//[InlineData (4, 4, 1, 2, 0)]
//[InlineData (4, 4, 2, 2, 0)]
//[InlineData (4, 4, 3, 2, 0)]
//[InlineData (4, 4, 4, 2, 0)]
// 012345
// ^----
// █░
[InlineData (2, 5, 0, 0)]
// -^---
// █░
[InlineData (2, 5, 1, 0)]
// --^--
// ░█
[InlineData (2, 5, 2, 1)]
// ---^-
// ░█
[InlineData (2, 5, 3, 1)]
// ----^
// ░█
[InlineData (2, 5, 4, 1)]
// 012345
// ^----
// █░░
[InlineData (3, 5, 0, 0)]
// -^---
// ░█░
[InlineData (3, 5, 1, 1)]
// --^--
// ░░█
[InlineData (3, 5, 2, 2)]
// ---^-
// ░░█
[InlineData (3, 5, 3, 2)]
// ----^
// ░░█
[InlineData (3, 5, 4, 2)]
// 0123456789
// ^-----
// █░░
[InlineData (3, 6, 0, 0)]
// -^----
// █░░
[InlineData (3, 6, 1, 1)]
// --^---
// ░█░
[InlineData (3, 6, 2, 1)]
// ---^--
// ░░█
[InlineData (3, 6, 3, 2)]
// ----^-
// ░░█
[InlineData (3, 6, 4, 2)]
// -----^
// ░░█
[InlineData (3, 6, 5, 2)]
// 012345
// ^----
// ███░
[InlineData (4, 5, 0, 0)]
// -^---
// ░███
[InlineData (4, 5, 1, 1)]
// --^--
// ░███
[InlineData (4, 5, 2, 1)]
// ---^-
// ░███
[InlineData (4, 5, 3, 1)]
// ----^
// ░███
[InlineData (4, 5, 4, 1)]
//// 01234
//// ^---------
//// ◄█░░►
//[InlineData (5, 10, 0, 1, 0)]
//// -^--------
//// ◄█░░►
//[InlineData (5, 10, 1, 1, 0)]
//// --^-------
//// ◄█░░►
//[InlineData (5, 10, 2, 1, 0)]
//// ---^------
//// ◄█░░►
//[InlineData (5, 10, 3, 1, 0)]
//// ----^----
//// ◄░█░►
//[InlineData (5, 10, 4, 1, 1)]
//// -----^---
//// ◄░█░►
//[InlineData (5, 10, 5, 1, 1)]
//// ------^--
//// ◄░░█►
//[InlineData (5, 10, 6, 1, 2)]
//// ------^--
//// ◄░░█►
//[InlineData (5, 10, 7, 1, 2)]
//// -------^-
//// ◄░░█►
//[InlineData (5, 10, 8, 1, 2)]
//// --------^
//// ◄░░█►
//[InlineData (5, 10, 9, 1, 2)]
// 0123456789
// ████░░░░
// ^-----------------
// 012345678901234567890123456789
// ░████░░░
// ----^-------------
// 012345678901234567890123456789
// ░░████░░
// --------^---------
// 012345678901234567890123456789
// ░░░████░
// ------------^-----
// 012345678901234567890123456789
// ░░░░████
// ----------------^--
// 0123456789
// ███░░░░░
// ^-----------------
// 012345678901234567890123456789
// ░░███░░░
// --------^---------
// 012345678901234567890123456789
// ░░░███░░
// ------------^-----
// 012345678901234567890123456789
// ░░░░███░
// ----------------^--
// 012345678901234567890123456789
// ░░░░░███
// ----------------^--
[InlineData (8, 18, 0, 0)]
[InlineData (8, 18, 1, 0)]
// 012345678901234567890123456789
// ░███░░░░
// --^---------------
[InlineData (8, 18, 2, 1)]
[InlineData (8, 18, 3, 2)]
[InlineData (8, 18, 4, 2)]
[InlineData (8, 18, 5, 2)]
[InlineData (8, 18, 6, 3)]
[InlineData (8, 18, 7, 4)]
[InlineData (8, 18, 8, 4)]
[InlineData (8, 18, 9, 4)]
// 012345678901234567890123456789
// ░░░░░███
// ----------^--------
[InlineData (8, 18, 10, 5)]
[InlineData (8, 18, 11, 5)]
[InlineData (8, 18, 12, 5)]
[InlineData (8, 18, 13, 5)]
[InlineData (8, 18, 14, 5)]
[InlineData (8, 18, 15, 5)]
[InlineData (8, 18, 16, 5)]
[InlineData (8, 18, 17, 5)]
[InlineData (8, 18, 18, 5)]
[InlineData (8, 18, 19, 5)]
[InlineData (8, 18, 20, 5)]
[InlineData (8, 18, 21, 5)]
[InlineData (8, 18, 22, 5)]
[InlineData (8, 18, 23, 5)]
// ------------------ ^
[InlineData (8, 18, 24, 5)]
[InlineData (8, 18, 25, 5)]
//// 0123456789
//// ◄████░░░░►
//// ^-----------------
//[InlineData (10, 20, 0, 5, 0)]
//[InlineData (10, 20, 1, 5, 0)]
//[InlineData (10, 20, 2, 5, 0)]
//[InlineData (10, 20, 3, 5, 0)]
//[InlineData (10, 20, 4, 5, 1)]
//[InlineData (10, 20, 5, 5, 1)]
//[InlineData (10, 20, 6, 5, 1)]
//[InlineData (10, 20, 7, 5, 2)]
//[InlineData (10, 20, 8, 5, 2)]
//[InlineData (10, 20, 9, 5, 2)]
//[InlineData (10, 20, 10, 5, 3)]
//[InlineData (10, 20, 11, 5, 3)]
//[InlineData (10, 20, 12, 5, 3)]
//[InlineData (10, 20, 13, 5, 3)]
//[InlineData (10, 20, 14, 5, 4)]
//[InlineData (10, 20, 15, 5, 4)]
//[InlineData (10, 20, 16, 5, 4)]
//[InlineData (10, 20, 17, 5, 5)]
//[InlineData (10, 20, 18, 5, 5)]
//[InlineData (10, 20, 19, 5, 5)]
//[InlineData (10, 20, 20, 5, 6)]
//[InlineData (10, 20, 21, 5, 6)]
//[InlineData (10, 20, 22, 5, 6)]
//[InlineData (10, 20, 23, 5, 6)]
//[InlineData (10, 20, 24, 5, 6)]
//[InlineData (10, 20, 25, 5, 6)]
public void CalculatePosition_Calculates_Correctly (int visibleContentSize, int scrollableContentSize, int contentPosition, int expectedSliderPosition)
{
// Arrange
// Act
var sliderPosition = ScrollSlider.CalculatePosition (
scrollableContentSize: scrollableContentSize,
visibleContentSize: visibleContentSize,
contentPosition: contentPosition,
sliderBounds: visibleContentSize,
NavigationDirection.Forward);
// Assert
Assert.Equal (expectedSliderPosition, sliderPosition);
}
[Theory]
[InlineData (8, 18, 0, 0)]
public void CalculateContentPosition_Calculates_Correctly (
int visibleContentSize,
int scrollableContentSize,
int sliderPosition,
int expectedContentPosition
)
{
// Arrange
// Act
var contentPosition = ScrollSlider.CalculateContentPosition (
scrollableContentSize: scrollableContentSize,
visibleContentSize: visibleContentSize,
sliderPosition: sliderPosition,
sliderBounds: visibleContentSize);
// Assert
Assert.Equal (expectedContentPosition, contentPosition);
}
[Theory]
[CombinatorialData]
public void ClampPosition_WithSuperView_Clamps_To_ViewPort_Minus_Size_If_VisibleContentSize_Not_Set ([CombinatorialRange (10, 10, 1)] int dimension, [CombinatorialRange (1, 5, 1)] int sliderSize, [CombinatorialRange (-1, 10, 2)] int sliderPosition, Orientation orientation)
{
View super = new ()
{
Id = "super",
Height = dimension,
Width = dimension,
};
var scrollSlider = new ScrollSlider
{
Orientation = orientation,
Size = sliderSize,
};
super.Add (scrollSlider);
super.Layout ();
Assert.Equal (dimension, scrollSlider.VisibleContentSize);
int clampedPosition = scrollSlider.ClampPosition (sliderPosition);
Assert.InRange (clampedPosition, 0, dimension - sliderSize);
}
[Theory]
[CombinatorialData]
public void ClampPosition_WithSuperView_Clamps_To_VisibleContentSize_Minus_Size ([CombinatorialRange (10, 10, 1)] int dimension, [CombinatorialRange (1, 5, 1)] int sliderSize, [CombinatorialRange (-1, 10, 2)] int sliderPosition, Orientation orientation)
{
View super = new ()
{
Id = "super",
Height = dimension + 2,
Width = dimension + 2,
};
var scrollSlider = new ScrollSlider
{
Orientation = orientation,
VisibleContentSize = dimension,
Size = sliderSize,
};
super.Add (scrollSlider);
super.Layout ();
int clampedPosition = scrollSlider.ClampPosition (sliderPosition);
Assert.InRange (clampedPosition, 0, dimension - sliderSize);
}
[Theory]
[CombinatorialData]
public void ClampPosition_NoSuperView_Clamps_To_VisibleContentSize_Minus_Size ([CombinatorialRange (10, 10, 1)] int dimension, [CombinatorialRange (1, 5, 1)] int sliderSize, [CombinatorialRange (-1, 10, 2)] int sliderPosition, Orientation orientation)
{
var scrollSlider = new ScrollSlider
{
Orientation = orientation,
VisibleContentSize = dimension,
Size = sliderSize,
};
int clampedPosition = scrollSlider.ClampPosition (sliderPosition);
Assert.InRange (clampedPosition, 0, dimension - sliderSize);
}
[Theory]
[CombinatorialData]
public void Position_Clamps_To_VisibleContentSize ([CombinatorialRange (0, 5, 1)] int dimension, [CombinatorialRange (1, 5, 1)] int sliderSize, [CombinatorialRange (-1, 10, 2)] int sliderPosition, Orientation orientation)
{
var scrollSlider = new ScrollSlider
{
Orientation = orientation,
VisibleContentSize = dimension,
Size = sliderSize,
Position = sliderPosition
};
Assert.True (scrollSlider.Position <= 5);
}
[Theory]
[CombinatorialData]
public void Position_Clamps_To_SuperView_Viewport ([CombinatorialRange (0, 5, 1)] int sliderSize, [CombinatorialRange (-2, 10, 2)] int sliderPosition, Orientation orientation)
{
var super = new View
{
Id = "super",
Width = 5,
Height = 5
};
var scrollSlider = new ScrollSlider
{
Orientation = orientation,
};
super.Add (scrollSlider);
scrollSlider.Size = sliderSize;
scrollSlider.Layout ();
scrollSlider.Position = sliderPosition;
Assert.True (scrollSlider.Position <= 5);
}
[Theory]
[CombinatorialData]
public void Position_Clamps_To_VisibleContentSize_With_SuperView ([CombinatorialRange (0, 5, 1)] int dimension, [CombinatorialRange (1, 5, 1)] int sliderSize, [CombinatorialRange (-2, 10, 2)] int sliderPosition, Orientation orientation)
{
var super = new View
{
Id = "super",
Width = 10,
Height = 10
};
var scrollSlider = new ScrollSlider
{
Orientation = orientation,
VisibleContentSize = dimension,
Size = sliderSize,
Position = sliderPosition
};
super.Add (scrollSlider);
scrollSlider.Size = sliderSize;
scrollSlider.Layout ();
scrollSlider.Position = sliderPosition;
Assert.True (scrollSlider.Position <= 5);
}
[Theory]
[SetupFakeDriver]
[InlineData (
3,
10,
1,
0,
Orientation.Vertical,
@"
┌───┐
│███│
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└───┘")]
[InlineData (
10,
1,
3,
0,
Orientation.Horizontal,
@"
┌──────────┐
│███ │
└──────────┘")]
[InlineData (
3,
10,
3,
0,
Orientation.Vertical,
@"
┌───┐
│███│
│███│
│███│
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└───┘")]
[InlineData (
3,
10,
5,
0,
Orientation.Vertical,
@"
┌───┐
│███│
│███│
│███│
│███│
│███│
│ │
│ │
│ │
│ │
│ │
└───┘")]
[InlineData (
3,
10,
5,
1,
Orientation.Vertical,
@"
┌───┐
│ │
│███│
│███│
│███│
│███│
│███│
│ │
│ │
│ │
│ │
└───┘")]
[InlineData (
3,
10,
5,
4,
Orientation.Vertical,
@"
┌───┐
│ │
│ │
│ │
│ │
│███│
│███│
│███│
│███│
│███│
│ │
└───┘")]
[InlineData (
3,
10,
5,
5,
Orientation.Vertical,
@"
┌───┐
│ │
│ │
│ │
│ │
│ │
│███│
│███│
│███│
│███│
│███│
└───┘")]
[InlineData (
3,
10,
5,
6,
Orientation.Vertical,
@"
┌───┐
│ │
│ │
│ │
│ │
│ │
│███│
│███│
│███│
│███│
│███│
└───┘")]
[InlineData (
3,
10,
10,
0,
Orientation.Vertical,
@"
┌───┐
│███│
│███│
│███│
│███│
│███│
│███│
│███│
│███│
│███│
│███│
└───┘")]
[InlineData (
3,
10,
10,
5,
Orientation.Vertical,
@"
┌───┐
│███│
│███│
│███│
│███│
│███│
│███│
│███│
│███│
│███│
│███│
└───┘")]
[InlineData (
3,
10,
11,
0,
Orientation.Vertical,
@"
┌───┐
│███│
│███│
│███│
│███│
│███│
│███│
│███│
│███│
│███│
│███│
└───┘")]
[InlineData (
10,
3,
5,
0,
Orientation.Horizontal,
@"
┌──────────┐
│█████ │
│█████ │
│█████ │
└──────────┘")]
[InlineData (
10,
3,
5,
1,
Orientation.Horizontal,
@"
┌──────────┐
│ █████ │
│ █████ │
│ █████ │
└──────────┘")]
[InlineData (
10,
3,
5,
4,
Orientation.Horizontal,
@"
┌──────────┐
│ █████ │
│ █████ │
│ █████ │
└──────────┘")]
[InlineData (
10,
3,
5,
5,
Orientation.Horizontal,
@"
┌──────────┐
│ █████│
│ █████│
│ █████│
└──────────┘")]
[InlineData (
10,
3,
5,
6,
Orientation.Horizontal,
@"
┌──────────┐
│ █████│
│ █████│
│ █████│
└──────────┘")]
[InlineData (
10,
3,
10,
0,
Orientation.Horizontal,
@"
┌──────────┐
│██████████│
│██████████│
│██████████│
└──────────┘")]
[InlineData (
10,
3,
10,
5,
Orientation.Horizontal,
@"
┌──────────┐
│██████████│
│██████████│
│██████████│
└──────────┘")]
[InlineData (
10,
3,
11,
0,
Orientation.Horizontal,
@"
┌──────────┐
│██████████│
│██████████│
│██████████│
└──────────┘")]
public void Draws_Correctly (int superViewportWidth, int superViewportHeight, int sliderSize, int position, Orientation orientation, string expected)
{
var super = new Window
{
Id = "super",
Width = superViewportWidth + 2,
Height = superViewportHeight + 2
};
var scrollSlider = new ScrollSlider
{
Orientation = orientation,
Size = sliderSize,
//Position = position,
};
Assert.Equal (sliderSize, scrollSlider.Size);
super.Add (scrollSlider);
scrollSlider.Position = position;
super.Layout ();
super.Draw ();
_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
}
}