Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2324,6 +2324,8 @@
where T : notnull { }
public static Spectre.Console.MultiSelectionPrompt<T> AddChoices<T>(this Spectre.Console.MultiSelectionPrompt<T> obj, T choice, System.Action<Spectre.Console.IMultiSelectionItem<T>> configurator)
where T : notnull { }
public static Spectre.Console.MultiSelectionPrompt<T> DefaultValue<T>(this Spectre.Console.MultiSelectionPrompt<T> obj, T? defaultValue)
where T : notnull { }
public static Spectre.Console.MultiSelectionPrompt<T> HighlightStyle<T>(this Spectre.Console.MultiSelectionPrompt<T> obj, Spectre.Console.Style highlightStyle)
where T : notnull { }
public static Spectre.Console.MultiSelectionPrompt<T> InstructionsText<T>(this Spectre.Console.MultiSelectionPrompt<T> obj, string? text)
Expand Down Expand Up @@ -2355,6 +2357,7 @@
public MultiSelectionPrompt(System.Collections.Generic.IEqualityComparer<T>? comparer = null) { }
public System.Func<System.Collections.Generic.List<T>>? CancelResult { get; set; }
public System.Func<T, string>? Converter { get; set; }
public T DefaultValue { get; set; }
public Spectre.Console.Style? HighlightStyle { get; set; }
public string? InstructionsText { get; set; }
public Spectre.Console.SelectionMode Mode { get; set; }
Expand Down Expand Up @@ -2698,6 +2701,8 @@
where T : notnull { }
public static Spectre.Console.SelectionPrompt<T> AddChoices<T>(this Spectre.Console.SelectionPrompt<T> obj, params T[] choices)
where T : notnull { }
public static Spectre.Console.SelectionPrompt<T> DefaultValue<T>(this Spectre.Console.SelectionPrompt<T> obj, T? defaultValue)
where T : notnull { }
public static Spectre.Console.SelectionPrompt<T> DisableSearch<T>(this Spectre.Console.SelectionPrompt<T> obj)
where T : notnull { }
public static Spectre.Console.SelectionPrompt<T> EnableSearch<T>(this Spectre.Console.SelectionPrompt<T> obj)
Expand All @@ -2722,9 +2727,10 @@
public sealed class SelectionPrompt<T> : Spectre.Console.IPrompt<T>
where T : notnull
{
public SelectionPrompt() { }
public SelectionPrompt(System.Collections.Generic.IEqualityComparer<T>? comparer = null) { }
public System.Func<T>? CancelResult { get; set; }
public System.Func<T, string>? Converter { get; set; }
public T DefaultValue { get; set; }
public Spectre.Console.Style? DisabledStyle { get; set; }
public Spectre.Console.Style? HighlightStyle { get; set; }
public Spectre.Console.SelectionMode Mode { get; set; }
Expand Down
14 changes: 8 additions & 6 deletions src/Spectre.Console.Tests/Unit/Prompts/ListPromptStateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@ namespace Spectre.Console.Tests.Unit;

public sealed class ListPromptStateTests
{
private ListPromptState<string> CreateListPromptState(int count, int pageSize, bool shouldWrap, bool searchEnabled)
private ListPromptState<string> CreateListPromptState(int count, int pageSize, bool shouldWrap, bool searchEnabled, int initialIndex = 0)
=> new(
Enumerable.Range(0, count).Select(i => new ListPromptItem<string>(i.ToString())).ToList(),
text => text,
pageSize, shouldWrap, SelectionMode.Independent, true, searchEnabled);
pageSize, shouldWrap, SelectionMode.Independent, true, searchEnabled, initialIndex);

[Fact]
public void Should_Have_Start_Index_Zero()
[Theory]
[InlineData(0)]
[InlineData(1)]
public void Should_Have_Specified_Start_Index(int index)
{
// Given
var state = CreateListPromptState(100, 10, false, false);
var state = CreateListPromptState(100, 10, false, false, initialIndex: index);

// When
/* noop */

// Then
state.Index.ShouldBe(0);
state.Index.ShouldBe(index);
}

[Theory]
Expand Down
254 changes: 254 additions & 0 deletions src/Spectre.Console.Tests/Unit/Prompts/MultiSelectionPromptTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,260 @@ public void Should_Return_CancelResult_On_Cancel_EmptyVersion()
// Then
selection.ShouldBe([]);
}

[Fact]
public void Should_Initially_Select_The_First_Item_When_No_Default_Is_Specified()
{
// Given
var console = new TestConsole();
console.Profile.Capabilities.Interactive = true;
console.Input.PushKey(ConsoleKey.Spacebar);
console.Input.PushKey(ConsoleKey.Enter);

// When
var prompt = new MultiSelectionPrompt<string>()
.AddChoices("First", "Second", "Third");

prompt.Show(console);

// Then
console.Lines.ShouldBe([
"> [ ] First ",
" [ ] Second ",
" [ ] Third ",
" ",
"(Press <space> to select, <enter> to accept)> [X] First ",
" [ ] Second ",
" [ ] Third ",
" ",
"(Press <space> to select, <enter> to accept)",
]);
}

[Fact]
public void Should_Initially_Select_The_Default_Item_When_It_Exists_In_The_Choices()
{
// Given
var console = new TestConsole();
console.Profile.Capabilities.Interactive = true;
console.Input.PushKey(ConsoleKey.Spacebar);
console.Input.PushKey(ConsoleKey.Enter);

// When
var prompt = new MultiSelectionPrompt<string>()
.Title("Select one")
.AddChoices("First", "Second", "Third")
.DefaultValue("Second");

prompt.Show(console);

// Then
console.Lines.ShouldBe([
"Select one ",
" ",
" [ ] First ",
"> [ ] Second ",
" [ ] Third ",
" ",
"(Press <space> to select, <enter> to accept)Select one ",
" ",
" [ ] First ",
"> [X] Second ",
" [ ] Third ",
" ",
"(Press <space> to select, <enter> to accept)",]);
}

[Fact]
public void Should_Initially_Select_The_First_Item_When_Default_Does_Not_Exist_In_The_Choices()
{
// Given
var console = new TestConsole();
console.Profile.Capabilities.Interactive = true;
console.Input.PushKey(ConsoleKey.Spacebar);
console.Input.PushKey(ConsoleKey.Enter);

// When
var prompt = new MultiSelectionPrompt<string>()
.Title("Select one")
.AddChoices("First", "Second", "Third")
.DefaultValue("Fourth");

prompt.Show(console);

// Then
console.Lines.ShouldBe([
"Select one ",
" ",
"> [ ] First ",
" [ ] Second ",
" [ ] Third ",
" ",
"(Press <space> to select, <enter> to accept)Select one ",
" ",
"> [X] First ",
" [ ] Second ",
" [ ] Third ",
" ",
"(Press <space> to select, <enter> to accept)",
]);
}

[Fact]
public void Should_Initially_Select_The_Default_Item_When_Scrolling_Is_Required_And_Item_Is_Not_Last()
{
// Given
var console = new TestConsole();
console.Profile.Capabilities.Interactive = true;
console.Input.PushKey(ConsoleKey.Spacebar);
console.Input.PushKey(ConsoleKey.Enter);

// When
var prompt = new MultiSelectionPrompt<string>()
.Title("Select one")
.AddChoices("First", "Second", "Third", "Fourth", "Fifth", "Sixth")
.DefaultValue("Third")
.PageSize(3);

prompt.Show(console);

// Then
console.Lines.ShouldBe([
"Select one ",
" ",
" [ ] Second ",
"> [ ] Third ",
" [ ] Fourth ",
" ",
"(Move up and down to reveal more choices) ",
"(Press <space> to select, <enter> to accept)Select one ", " ", " [ ] Second ", "> [X] Third ", " [ ] Fourth ", " ", "(Move up and down to reveal more choices) ",
"(Press <space> to select, <enter> to accept)",
]);
}

[Fact]
public void Should_Initially_Select_The_Default_Item_When_Scrolling_Is_Required_And_Item_Is_Last()
{
// Given
var console = new TestConsole();
console.Profile.Capabilities.Interactive = true;
console.Input.PushKey(ConsoleKey.Spacebar);
console.Input.PushKey(ConsoleKey.Enter);

// When
var prompt = new MultiSelectionPrompt<string>()
.Title("Select one")
.AddChoices("First", "Second", "Third", "Fourth", "Fifth", "Sixth")
.DefaultValue("Sixth")
.PageSize(3);

prompt.Show(console);

// Then
console.Lines.ShouldBe([
"Select one ",
" ",
" [ ] Fourth ",
" [ ] Fifth ",
"> [ ] Sixth ",
" ",
"(Move up and down to reveal more choices) ",
"(Press <space> to select, <enter> to accept)Select one ",
" ",
" [ ] Fourth ",
" [ ] Fifth ",
"> [X] Sixth ",
" ",
"(Move up and down to reveal more choices) ",
"(Press <space> to select, <enter> to accept)",
]);
}

[Fact]
public void Should_Initially_Select_The_Default_Value_When_Skipping_Unselectable_Items_And_Default_Value_Is_Leaf()
{
// Given
var console = new TestConsole();
console.Profile.Capabilities.Interactive = true;
console.Input.PushKey(ConsoleKey.Spacebar);
console.Input.PushKey(ConsoleKey.Enter);

// When
var prompt = new MultiSelectionPrompt<string>()
.Title("Select one")
.AddChoiceGroup("Group one", "First", "Second")
.AddChoiceGroup("Group two", "Third", "Fourth")
.Mode(SelectionMode.Leaf)
.DefaultValue("Third");

prompt.Show(console);

// Then
console.Lines.ShouldBe([
"Select one ",
" ",
" [ ] Group one ",
" [ ] First ",
" [ ] Second ",
" [ ] Group two ",
" > [ ] Third ",
" [ ] Fourth ",
" ",
"(Press <space> to select, <enter> to accept)Select one ",
" ",
" [ ] Group one ",
" [ ] First ",
" [ ] Second ",
" [ ] Group two ",
" > [X] Third ",
" [ ] Fourth ",
" ",
"(Press <space> to select, <enter> to accept)",
]);
}

[Fact]
public void Should_Initially_Select_The_First_Leaf_When_Skipping_Unselectable_Items_And_Default_Value_Is_Not_Leaf()
{
// Given
var console = new TestConsole();
console.Profile.Capabilities.Interactive = true;
console.Input.PushKey(ConsoleKey.Spacebar);
console.Input.PushKey(ConsoleKey.Enter);

// When
var prompt = new MultiSelectionPrompt<string>()
.Title("Select one")
.AddChoiceGroup("Group one", "First", "Second")
.AddChoiceGroup("Group two", "Third", "Fourth")
.Mode(SelectionMode.Leaf)
.DefaultValue("Group two");

prompt.Show(console);

// Then
console.Lines.ShouldBe([
"Select one ",
" ",
" [ ] Group one ",
" [ ] First ",
" [ ] Second ",
"> [ ] Group two ",
" [ ] Third ",
" [ ] Fourth ",
" ",
"(Press <space> to select, <enter> to accept)Select one ",
" ",
" [ ] Group one ",
" [ ] First ",
" [ ] Second ",
"> [X] Group two ",
" [X] Third ",
" [X] Fourth ",
" ",
"(Press <space> to select, <enter> to accept)",
]);
}
}

file sealed class CustomItem
Expand Down
Loading