From 1fa6bd25eb16e4ace4990bd9638cbd843cb57a5a Mon Sep 17 00:00:00 2001 From: luthfiampas Date: Sun, 7 Mar 2021 14:27:42 +0700 Subject: [PATCH 1/3] better TextBox.MaxLength tests --- .../TextBoxTests.cs | 62 +++++++++++++++---- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs b/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs index 6ac7799828..9f09c19110 100644 --- a/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs @@ -646,22 +646,49 @@ namespace Avalonia.Controls.UnitTests Assert.Null(target.Text); } } - - [Fact] - public void Text_Box_MaxLength_Work_Properly() + + [Theory] + [InlineData("abc", "d", 3, 0, 0, false, "abc")] + [InlineData("abc", "dd", 4, 3, 3, false, "abcd")] + [InlineData("abc", "ddd", 3, 0, 2, true, "ddc")] + [InlineData("abc", "dddd", 4, 1, 3, true, "addd")] + [InlineData("abc", "ddddd", 5, 3, 3, true, "abcdd")] + public void MaxLength_Works_Properly( + string initalText, + string textInput, + int maxLength, + int selectionStart, + int selectionEnd, + bool fromClipboard, + string expected) { using (UnitTestApplication.Start(Services)) { var target = new TextBox { Template = CreateTemplate(), - Text = "abc", - MaxLength = 3, + Text = initalText, + MaxLength = maxLength, + SelectionStart = selectionStart, + SelectionEnd = selectionEnd }; - - RaiseKeyEvent(target, Key.D, KeyModifiers.None); - - Assert.Equal("abc", target.Text); + + if (fromClipboard) + { + AvaloniaLocator.CurrentMutable.Bind().ToSingleton(); + + var clipboard = AvaloniaLocator.CurrentMutable.GetService(); + clipboard.SetTextAsync(textInput).GetAwaiter().GetResult(); + + RaiseKeyEvent(target, Key.V, KeyModifiers.Control); + clipboard.ClearAsync().GetAwaiter().GetResult(); + } + else + { + RaiseTextEvent(target, textInput); + } + + Assert.Equal(expected, target.Text); } } @@ -758,11 +785,22 @@ namespace Avalonia.Controls.UnitTests private class ClipboardStub : IClipboard // in order to get tests working that use the clipboard { - public Task GetTextAsync() => Task.FromResult(""); + private string _text; + + public Task GetTextAsync() => Task.FromResult(_text); - public Task SetTextAsync(string text) => Task.CompletedTask; + public Task SetTextAsync(string text) + { + _text = text; + return Task.CompletedTask; + } - public Task ClearAsync() => Task.CompletedTask; + public Task ClearAsync() + { + _text = null; + return Task.CompletedTask; + } + public Task SetDataObjectAsync(IDataObject data) => Task.CompletedTask; public Task GetFormatsAsync() => Task.FromResult(Array.Empty()); From 17971b884187176615196564569e314a99c7544b Mon Sep 17 00:00:00 2001 From: luthfiampas Date: Sun, 7 Mar 2021 14:40:41 +0700 Subject: [PATCH 2/3] TextBox.MaxLength should respect occurred text from clipboard --- src/Avalonia.Controls/TextBox.cs | 43 +++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index 54d3af9b59..44d1a1c489 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -514,21 +514,36 @@ namespace Avalonia.Controls private void HandleTextInput(string input) { - if (!IsReadOnly) + if (IsReadOnly) { - input = RemoveInvalidCharacters(input); - string text = Text ?? string.Empty; - int caretIndex = CaretIndex; - if (!string.IsNullOrEmpty(input) && (MaxLength == 0 || input.Length + text.Length - (Math.Abs(SelectionStart - SelectionEnd)) <= MaxLength)) - { - DeleteSelection(); - caretIndex = CaretIndex; - text = Text ?? string.Empty; - SetTextInternal(text.Substring(0, caretIndex) + input + text.Substring(caretIndex)); - CaretIndex += input.Length; - ClearSelection(); - _undoRedoHelper.DiscardRedo(); - } + return; + } + + input = RemoveInvalidCharacters(input); + + if (string.IsNullOrEmpty(input)) + { + return; + } + + string text = Text ?? string.Empty; + int caretIndex = CaretIndex; + int estimatedLength = input.Length + text.Length - Math.Abs(SelectionStart - SelectionEnd); + + if (MaxLength > 0 && estimatedLength > MaxLength) + { + input = input.Remove(Math.Max(0, input.Length - (estimatedLength - MaxLength))); + } + + if (!string.IsNullOrEmpty(input)) + { + DeleteSelection(); + caretIndex = CaretIndex; + text = Text ?? string.Empty; + SetTextInternal(text.Substring(0, caretIndex) + input + text.Substring(caretIndex)); + CaretIndex += input.Length; + ClearSelection(); + _undoRedoHelper.DiscardRedo(); } } From 9899fe5e81849363c13ba7f0707830369561d50b Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 16 Mar 2021 09:51:52 +0100 Subject: [PATCH 3/3] Clarify naming. --- src/Avalonia.Controls/TextBox.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index 44d1a1c489..1d75f08a41 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -528,11 +528,11 @@ namespace Avalonia.Controls string text = Text ?? string.Empty; int caretIndex = CaretIndex; - int estimatedLength = input.Length + text.Length - Math.Abs(SelectionStart - SelectionEnd); + int newLength = input.Length + text.Length - Math.Abs(SelectionStart - SelectionEnd); - if (MaxLength > 0 && estimatedLength > MaxLength) + if (MaxLength > 0 && newLength > MaxLength) { - input = input.Remove(Math.Max(0, input.Length - (estimatedLength - MaxLength))); + input = input.Remove(Math.Max(0, input.Length - (newLength - MaxLength))); } if (!string.IsNullOrEmpty(input))