Skip to content

Commit b768836

Browse files
authored
Add BasicScrollingConsole to support test cases for scrolling up scenarios (#3081)
1 parent 8e6893c commit b768836

File tree

7 files changed

+848
-56
lines changed

7 files changed

+848
-56
lines changed

PSReadLine/Completion.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,7 @@ private void MenuCompleteImpl(Menu menu, CommandCompletion completions)
867867
// getting shorter or longer.
868868
var endOfCommandLine = ConvertOffsetToPoint(_buffer.Length);
869869
var topAdjustment = (endOfCommandLine.Y + 1) - menu.Top;
870+
int oldInitialY = _initialY;
870871

871872
if (topAdjustment != 0)
872873
{
@@ -877,6 +878,14 @@ private void MenuCompleteImpl(Menu menu, CommandCompletion completions)
877878
// Render did not clear the rest of the command line which flowed
878879
// into the menu, so we must do that here.
879880
menu.SaveCursor();
881+
882+
if (oldInitialY > _initialY)
883+
{
884+
// Scrolling happened when drawing the menu, so we need to adjust
885+
// this point as it was calculated before drawing the menu.
886+
endOfCommandLine.Y -= oldInitialY - _initialY;
887+
}
888+
880889
_console.SetCursorPosition(endOfCommandLine.X, endOfCommandLine.Y);
881890
_console.Write(Spaces(_console.BufferWidth - endOfCommandLine.X));
882891
menu.RestoreCursor();

PSReadLine/ReadLine.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,9 @@ private static string GetPrompt()
11081108

11091109
internal static bool IsRunningCI(IConsole console)
11101110
{
1111-
return console.GetType().FullName == "Test.TestConsole";
1111+
Type consoleType = console.GetType();
1112+
return consoleType.FullName == "Test.TestConsole"
1113+
|| consoleType.BaseType.FullName == "Test.TestConsole";
11121114
}
11131115
}
11141116
}

test/CompletionTest.cs

Lines changed: 479 additions & 0 deletions
Large diffs are not rendered by default.

test/DynamicHelpTest.cs

Lines changed: 153 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public void DynHelp_GetParameterHelpMultiLine_And_Clear()
159159

160160
Test("Get-MultiLineHelp -OneAndHalf", Keys(
161161
"Get-MultiLineHelp -OneAndHalf", _.Alt_h,
162-
CheckThat(() => AssertScreenIs(9,
162+
CheckThat(() => AssertScreenIs(8,
163163
TokenClassification.Command, "Get-MultiLineHelp",
164164
TokenClassification.None, " ",
165165
TokenClassification.Parameter, "-OneAndHalf",
@@ -172,8 +172,7 @@ public void DynHelp_GetParameterHelpMultiLine_And_Clear()
172172
TokenClassification.None, "60 characters but shorter than 120.",
173173
NextLine,
174174
TokenClassification.None, "Required: false, Position: 0, Default Value: None, Pipeline ",
175-
NextLine,
176-
"Input: True (ByPropertyName, ByValue), WildCard: false")),
175+
TokenClassification.None, "Input: True (ByPropertyName, ByValue), WildCard: false")),
177176
_.LeftArrow,
178177
CheckThat(() => AssertScreenIs(1,
179178
TokenClassification.Command, "Get-MultiLineHelp",
@@ -183,6 +182,157 @@ public void DynHelp_GetParameterHelpMultiLine_And_Clear()
183182
));
184183
}
185184

185+
[SkippableFact]
186+
public void DynHelp_GetParameterHelpMultiLine_And_Clear_WithScrolling1()
187+
{
188+
// This test case covers the fix to https://github.com/PowerShell/PSReadLine/issues/2950.
189+
var basicScrollingConsole = new BasicScrollingConsole(keyboardLayout: _, width: 60, height: 10);
190+
TestSetup(basicScrollingConsole, KeyMode.Cmd);
191+
192+
// Write 12 new-lines, so that the next input will be at the last line of the screen buffer.
193+
basicScrollingConsole.Write(new string('\n', 12));
194+
AssertCursorLeftTopIs(0, 9);
195+
196+
Test("Get-MultiLineHelp -OneAndHalf", Keys(
197+
"Get-MultiLineHelp -OneAndHalf",
198+
CheckThat(() => AssertCursorLeftTopIs(29, 9)),
199+
_.Alt_h,
200+
CheckThat(() => AssertCursorLeftTopIs(29, 2)),
201+
CheckThat(() => AssertScreenIs(top: 12, lines: 8,
202+
TokenClassification.Command, "Get-MultiLineHelp",
203+
TokenClassification.None, " ",
204+
TokenClassification.Parameter, "-OneAndHalf",
205+
NextLine,
206+
NextLine,
207+
TokenClassification.None, $"-Date <name>",
208+
NextLine,
209+
NextLine,
210+
TokenClassification.None, "DESC: Some very long description that is over the buffer width of ",
211+
TokenClassification.None, "60 characters but shorter than 120.",
212+
NextLine,
213+
TokenClassification.None, "Required: false, Position: 0, Default Value: None, Pipeline ",
214+
TokenClassification.None, "Input: True (ByPropertyName, ByValue), WildCard: false")),
215+
_.Alt_h,
216+
CheckThat(() => AssertCursorLeftTopIs(29, 2)),
217+
CheckThat(() => AssertScreenIs(top: 12, lines: 8,
218+
TokenClassification.Command, "Get-MultiLineHelp",
219+
TokenClassification.None, " ",
220+
TokenClassification.Parameter, "-OneAndHalf", NextLine,
221+
NextLine,
222+
NextLine,
223+
NextLine,
224+
NextLine,
225+
NextLine,
226+
NextLine,
227+
NextLine)),
228+
_.Alt_h,
229+
CheckThat(() => AssertCursorLeftTopIs(29, 2)),
230+
CheckThat(() => AssertScreenIs(top: 12, lines: 8,
231+
TokenClassification.Command, "Get-MultiLineHelp",
232+
TokenClassification.None, " ",
233+
TokenClassification.Parameter, "-OneAndHalf",
234+
NextLine,
235+
NextLine,
236+
TokenClassification.None, $"-Date <name>",
237+
NextLine,
238+
NextLine,
239+
TokenClassification.None, "DESC: Some very long description that is over the buffer width of ",
240+
TokenClassification.None, "60 characters but shorter than 120.",
241+
NextLine,
242+
TokenClassification.None, "Required: false, Position: 0, Default Value: None, Pipeline ",
243+
TokenClassification.None, "Input: True (ByPropertyName, ByValue), WildCard: false")),
244+
_.LeftArrow,
245+
CheckThat(() => AssertCursorLeftTopIs(29, 2)),
246+
CheckThat(() => AssertScreenIs(top: 12, lines: 8,
247+
TokenClassification.Command, "Get-MultiLineHelp",
248+
TokenClassification.None, " ",
249+
TokenClassification.Parameter, "-OneAndHalf", NextLine,
250+
NextLine,
251+
NextLine,
252+
NextLine,
253+
NextLine,
254+
NextLine,
255+
NextLine,
256+
NextLine)),
257+
_.Enter),
258+
resetCursor: false);
259+
}
260+
261+
[SkippableFact]
262+
public void DynHelp_GetParameterHelpMultiLine_And_Clear_WithScrolling2()
263+
{
264+
// This test case covers the new changes in 'RecomputeInitialCoords', to verify that the
265+
// previous cursor position gets updated when scrolling happens.
266+
var basicScrollingConsole = new BasicScrollingConsole(keyboardLayout: _, width: 60, height: 10);
267+
TestSetup(basicScrollingConsole, KeyMode.Cmd);
268+
269+
// Write 12 new-lines, so that the next input will be at the last line of the screen buffer.
270+
basicScrollingConsole.Write(new string('\n', 12));
271+
AssertCursorLeftTopIs(0, 9);
272+
273+
Test("Get-MultiLineHelp -OneAndHalf", Keys(
274+
"Get-MultiLineHelp -OneAndHalf",
275+
CheckThat(() => AssertCursorLeftTopIs(29, 9)),
276+
_.Alt_h,
277+
CheckThat(() => AssertCursorLeftTopIs(29, 2)),
278+
CheckThat(() => AssertScreenIs(top: 12, lines: 8,
279+
TokenClassification.Command, "Get-MultiLineHelp",
280+
TokenClassification.None, " ",
281+
TokenClassification.Parameter, "-OneAndHalf",
282+
NextLine,
283+
NextLine,
284+
TokenClassification.None, $"-Date <name>",
285+
NextLine,
286+
NextLine,
287+
TokenClassification.None, "DESC: Some very long description that is over the buffer width of ",
288+
TokenClassification.None, "60 characters but shorter than 120.",
289+
NextLine,
290+
TokenClassification.None, "Required: false, Position: 0, Default Value: None, Pipeline ",
291+
TokenClassification.None, "Input: True (ByPropertyName, ByValue), WildCard: false")),
292+
_.Escape,
293+
CheckThat(() => AssertCursorLeftTopIs(29, 2)),
294+
CheckThat(() => AssertScreenIs(top: 12, lines: 8,
295+
TokenClassification.Command, "Get-MultiLineHelp",
296+
TokenClassification.None, " ",
297+
TokenClassification.Parameter, "-OneAndHalf", NextLine,
298+
NextLine,
299+
NextLine,
300+
NextLine,
301+
NextLine,
302+
NextLine,
303+
NextLine,
304+
NextLine)),
305+
// Write more characters after clearing the inline help content, verify that the initial coordinates are up-to-date.
306+
"abc",
307+
CheckThat(() => AssertCursorLeftTopIs(32, 2)),
308+
CheckThat(() => AssertScreenIs(top: 12, lines: 8,
309+
TokenClassification.Command, "Get-MultiLineHelp",
310+
TokenClassification.None, " ",
311+
TokenClassification.Parameter, "-OneAndHalfabc", NextLine,
312+
NextLine,
313+
NextLine,
314+
NextLine,
315+
NextLine,
316+
NextLine,
317+
NextLine,
318+
NextLine)),
319+
_.Backspace, _.Backspace, _.Backspace,
320+
CheckThat(() => AssertCursorLeftTopIs(29, 2)),
321+
CheckThat(() => AssertScreenIs(top: 12, lines: 8,
322+
TokenClassification.Command, "Get-MultiLineHelp",
323+
TokenClassification.None, " ",
324+
TokenClassification.Parameter, "-OneAndHalf", NextLine,
325+
NextLine,
326+
NextLine,
327+
NextLine,
328+
NextLine,
329+
NextLine,
330+
NextLine,
331+
NextLine)),
332+
_.Enter),
333+
resetCursor: false);
334+
}
335+
186336
[SkippableFact]
187337
public void DynHelp_GetParameterHelpTwoLines_And_Clear()
188338
{

test/InlinePredictionTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ public void Inline_HistoryAndPluginSource_ExecutionStatus()
731731
[SkippableFact]
732732
public void Inline_TruncateVeryLongSuggestion()
733733
{
734-
TestSetup(new TestConsole(width: 10, height: 2, keyboardLayout: _), KeyMode.Cmd);
734+
TestSetup(new TestConsole(keyboardLayout: _, width: 10, height: 2), KeyMode.Cmd);
735735
using var disp = SetPrediction(PredictionSource.History, PredictionViewStyle.InlineView);
736736

737737
// Truncate long suggestion to make sure the user input is not scrolled up-off the console buffer.

0 commit comments

Comments
 (0)