OSDN Git Service

Merge pull request #281 from opentween/format-status-test
authorupsilon <kim.upsilon@bucyou.net>
Thu, 14 Dec 2023 19:10:25 +0000 (04:10 +0900)
committerGitHub <noreply@github.com>
Thu, 14 Dec 2023 19:10:25 +0000 (04:10 +0900)
TweenMain.FormatStatusTextに対するテストコードを追加

OpenTween.Tests/MyCommonTest.cs
OpenTween.Tests/TweenMainTest.cs
OpenTween/MyCommon.cs
OpenTween/Tween.cs

index 1261d47..8ebb2a1 100644 (file)
@@ -157,14 +157,14 @@ namespace OpenTween
             => Assert.Equal(expected, MyCommon.IsValidEmail(email));
 
         [Theory]
-        [InlineData(Keys.Shift, new[] { Keys.Shift }, true)]
-        [InlineData(Keys.Shift, new[] { Keys.Control }, false)]
-        [InlineData(Keys.Control | Keys.Alt, new[] { Keys.Control }, true)]
-        [InlineData(Keys.Control | Keys.Alt, new[] { Keys.Alt }, true)]
-        [InlineData(Keys.Control | Keys.Alt, new[] { Keys.Control, Keys.Alt }, true)]
-        [InlineData(Keys.Control | Keys.Alt, new[] { Keys.Shift }, false)]
-        public void IsKeyDownTest(Keys modifierKeys, Keys[] checkKeys, bool expected)
-            => Assert.Equal(expected, MyCommon.IsKeyDownInternal(modifierKeys, checkKeys));
+        [InlineData(Keys.Shift, Keys.Shift, true)]
+        [InlineData(Keys.Shift, Keys.Control, false)]
+        [InlineData(Keys.Control | Keys.Alt, Keys.Control, true)]
+        [InlineData(Keys.Control | Keys.Alt, Keys.Alt, true)]
+        [InlineData(Keys.Control | Keys.Alt, Keys.Control | Keys.Alt, true)]
+        [InlineData(Keys.Control | Keys.Alt, Keys.Shift, false)]
+        public void IsKeyDownTest(Keys modifierKeys, Keys checkKeys, bool expected)
+            => Assert.Equal(expected, MyCommon.IsKeyDown(modifierKeys, checkKeys));
 
         [Fact]
         public void GetAssemblyNameTest()
index ea14617..8beba3b 100644 (file)
@@ -24,6 +24,7 @@ using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Text;
+using System.Text.RegularExpressions;
 using System.Windows.Forms;
 using OpenTween.Api;
 using OpenTween.Api.DataModel;
@@ -38,8 +39,11 @@ namespace OpenTween
 {
     public class TweenMainTest
     {
-        [WinFormsFact]
-        public void Initialize_Test()
+        private record TestContext(
+            SettingManager Settings
+        );
+
+        private void UsingTweenMain(Action<TweenMain, TestContext> func)
         {
             var settings = new SettingManager("");
             var tabinfo = new TabInformations();
@@ -50,6 +54,224 @@ namespace OpenTween
             var thumbnailGenerator = new ThumbnailGenerator(new(autoupdate: false));
 
             using var tweenMain = new TweenMain(settings, tabinfo, twitter, imageCache, iconAssets, thumbnailGenerator);
+            var context = new TestContext(settings);
+
+            func(tweenMain, context);
+        }
+
+        [WinFormsFact]
+        public void Initialize_Test()
+            => this.UsingTweenMain((_, _) => { });
+
+        [WinFormsFact]
+        public void FormatStatusText_NewLineTest()
+        {
+            this.UsingTweenMain((tweenMain, _) =>
+            {
+                Assert.Equal("aaa\nbbb", tweenMain.FormatStatusText("aaa\r\nbbb"));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_NewLineInDMTest()
+        {
+            this.UsingTweenMain((tweenMain, _) =>
+            {
+                // DM にも適用する
+                Assert.Equal("D opentween aaa\nbbb", tweenMain.FormatStatusText("D opentween aaa\r\nbbb"));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_SeparateUrlAndFullwidthCharacter_EnabledTest()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                tweenMain.SeparateUrlAndFullwidthCharacter = true;
+                Assert.Equal("https://example.com/ あああ", tweenMain.FormatStatusText("https://example.com/あああ"));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_SeparateUrlAndFullwidthCharacter_DisabledTest()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                tweenMain.SeparateUrlAndFullwidthCharacter = false;
+                Assert.Equal("https://example.com/あああ", tweenMain.FormatStatusText("https://example.com/あああ"));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_ReplaceFullwidthSpace_EnabledTest()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                context.Settings.Common.WideSpaceConvert = true;
+                Assert.Equal("aaa bbb", tweenMain.FormatStatusText("aaa bbb"));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_ReplaceFullwidthSpaceInDM_EnabledTest()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                context.Settings.Common.WideSpaceConvert = true;
+
+                // DM にも適用する
+                Assert.Equal("D opentween aaa bbb", tweenMain.FormatStatusText("D opentween aaa bbb"));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_ReplaceFullwidthSpace_DisabledTest()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                context.Settings.Common.WideSpaceConvert = false;
+                Assert.Equal("aaa bbb", tweenMain.FormatStatusText("aaa bbb"));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_UseRecommendedFooter_Test()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                context.Settings.Local.UseRecommendStatus = true;
+                Assert.Matches(new Regex(@"^aaa \[TWNv\d+\]$"), tweenMain.FormatStatusText("aaa"));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_CustomFooterText_Test()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                context.Settings.Local.StatusText = "foo";
+                Assert.Equal("aaa foo", tweenMain.FormatStatusText("aaa"));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_DisableFooterIfSendingDM_Test()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                context.Settings.Local.StatusText = "foo";
+
+                // DM の場合はフッターを無効化する
+                Assert.Equal("D opentween aaa", tweenMain.FormatStatusText("D opentween aaa"));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_DisableFooterIfContainsUnofficialRT_Test()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                context.Settings.Local.StatusText = "foo";
+
+                // 非公式 RT を含む場合はフッターを無効化する
+                Assert.Equal("aaa RT @foo: bbb", tweenMain.FormatStatusText("aaa RT @foo: bbb"));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_DisableFooterIfPostByEnterAndPressedShiftKey_Test()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                context.Settings.Common.PostCtrlEnter = false;
+                context.Settings.Common.PostShiftEnter = false; // Enter で投稿する設定
+                context.Settings.Local.StatusText = "foo";
+                context.Settings.Local.StatusMultiline = false; // 単一行モード
+
+                // Shift キーが押されている場合はフッターを無効化する
+                Assert.Equal("aaa", tweenMain.FormatStatusText("aaa", modifierKeys: Keys.Shift));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_DisableFooterIfPostByEnterAndPressedCtrlKeyAndMultilineMode_Test()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                context.Settings.Common.PostCtrlEnter = false;
+                context.Settings.Common.PostShiftEnter = false; // Enter で投稿する設定
+                context.Settings.Local.StatusText = "foo";
+                context.Settings.Local.StatusMultiline = true; // 複数行モード
+
+                // Ctrl キーが押されている場合はフッターを無効化する
+                Assert.Equal("aaa", tweenMain.FormatStatusText("aaa", modifierKeys: Keys.Control));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_DisableFooterIfPostByShiftEnterAndPressedControlKey_Test()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                context.Settings.Common.PostCtrlEnter = false;
+                context.Settings.Common.PostShiftEnter = true; // Shift+Enter で投稿する設定
+                context.Settings.Local.StatusText = "foo";
+
+                // Ctrl キーが押されている場合はフッターを無効化する
+                Assert.Equal("aaa", tweenMain.FormatStatusText("aaa", modifierKeys: Keys.Control));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_EnableFooterIfPostByShiftEnter_Test()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                context.Settings.Common.PostCtrlEnter = false;
+                context.Settings.Common.PostShiftEnter = true; // Shift+Enter で投稿する設定
+                context.Settings.Local.StatusText = "foo";
+
+                // Shift+Enter で投稿する場合、Ctrl キーが押されていなければフッターを付ける
+                Assert.Equal("aaa foo", tweenMain.FormatStatusText("aaa", modifierKeys: Keys.Shift));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_DisableFooterIfPostByCtrlEnterAndPressedShiftKey_Test()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                context.Settings.Common.PostCtrlEnter = true; // Ctrl+Enter で投稿する設定
+                context.Settings.Common.PostShiftEnter = false;
+                context.Settings.Local.StatusText = "foo";
+
+                // Shift キーが押されている場合はフッターを無効化する
+                Assert.Equal("aaa", tweenMain.FormatStatusText("aaa", modifierKeys: Keys.Shift));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_EnableFooterIfPostByCtrlEnter_Test()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                context.Settings.Common.PostCtrlEnter = true; // Ctrl+Enter で投稿する設定
+                context.Settings.Common.PostShiftEnter = false;
+                context.Settings.Local.StatusText = "foo";
+
+                // Ctrl+Enter で投稿する場合、Shift キーが押されていなければフッターを付ける
+                Assert.Equal("aaa foo", tweenMain.FormatStatusText("aaa", modifierKeys: Keys.Control));
+            });
+        }
+
+        [WinFormsFact]
+        public void FormatStatusText_PreventSmsCommand_Test()
+        {
+            this.UsingTweenMain((tweenMain, context) =>
+            {
+                // 「D+」などから始まる文字列をツイートしようとすると SMS コマンドと誤認されてエラーが返される問題の回避策
+                Assert.Equal("\u200bd+aaaa", tweenMain.FormatStatusText("d+aaaa"));
+            });
         }
 
         [Fact]
index e6b1f3d..0732c2e 100644 (file)
@@ -757,20 +757,11 @@ namespace OpenTween
         /// </summary>
         /// <param name="keys">状態を調べるキー</param>
         /// <returns><paramref name="keys"/> で指定された修飾キーがすべて押されている状態であれば true。それ以外であれば false。</returns>
-        public static bool IsKeyDown(params Keys[] keys)
-            => MyCommon.IsKeyDownInternal(Control.ModifierKeys, keys);
+        public static bool IsKeyDown(Keys keys)
+            => MyCommon.IsKeyDown(Control.ModifierKeys, keys);
 
-        internal static bool IsKeyDownInternal(Keys modifierKeys, Keys[] targetKeys)
-        {
-            foreach (var key in targetKeys)
-            {
-                if ((modifierKeys & key) != key)
-                {
-                    return false;
-                }
-            }
-            return true;
-        }
+        public static bool IsKeyDown(Keys modifierKeys, Keys targetKeys)
+            => (modifierKeys & targetKeys) == targetKeys;
 
         /// <summary>
         /// アプリケーションのアセンブリ名を取得します。
index 0d2de5d..ae3c660 100644 (file)
@@ -208,7 +208,9 @@ namespace OpenTween
         private readonly DebounceTimer saveConfigDebouncer;
 
         private readonly string recommendedStatusFooter;
-        private bool urlMultibyteSplit = false;
+
+        internal bool SeparateUrlAndFullwidthCharacter { get; set; } = false;
+
         private bool preventSmsCommand = true;
 
         // URL短縮のUndo用
@@ -3528,14 +3530,17 @@ namespace OpenTween
             return this.FormatStatusText(statusText);
         }
 
+        internal string FormatStatusText(string statusText)
+            => this.FormatStatusText(statusText, Control.ModifierKeys);
+
         /// <summary>
         /// ツイート投稿前のフッター付与などの前処理を行います
         /// </summary>
-        private string FormatStatusText(string statusText)
+        internal string FormatStatusText(string statusText, Keys modifierKeys)
         {
             statusText = statusText.Replace("\r\n", "\n");
 
-            if (this.urlMultibyteSplit)
+            if (this.SeparateUrlAndFullwidthCharacter)
             {
                 // URLと全角文字の切り離し
                 statusText = Regex.Replace(statusText, @"https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#^]+", "$& ");
@@ -3554,14 +3559,14 @@ namespace OpenTween
             bool disableFooter;
             if (this.settings.Common.PostShiftEnter)
             {
-                disableFooter = MyCommon.IsKeyDown(Keys.Control);
+                disableFooter = MyCommon.IsKeyDown(modifierKeys, Keys.Control);
             }
             else
             {
-                if (this.StatusText.Multiline && !this.settings.Common.PostCtrlEnter)
-                    disableFooter = MyCommon.IsKeyDown(Keys.Control);
+                if (this.settings.Local.StatusMultiline && !this.settings.Common.PostCtrlEnter)
+                    disableFooter = MyCommon.IsKeyDown(modifierKeys, Keys.Control);
                 else
-                    disableFooter = MyCommon.IsKeyDown(Keys.Shift);
+                    disableFooter = MyCommon.IsKeyDown(modifierKeys, Keys.Shift);
             }
 
             if (statusText.Contains("RT @"))
@@ -8186,14 +8191,14 @@ namespace OpenTween
 
         private void MenuItemHelp_DropDownOpening(object sender, EventArgs e)
         {
-            if (MyCommon.DebugBuild || MyCommon.IsKeyDown(Keys.CapsLock, Keys.Control, Keys.Shift))
+            if (MyCommon.DebugBuild || MyCommon.IsKeyDown(Keys.CapsLock | Keys.Control | Keys.Shift))
                 this.DebugModeToolStripMenuItem.Visible = true;
             else
                 this.DebugModeToolStripMenuItem.Visible = false;
         }
 
         private void UrlMultibyteSplitMenuItem_CheckedChanged(object sender, EventArgs e)
-            => this.urlMultibyteSplit = ((ToolStripMenuItem)sender).Checked;
+            => this.SeparateUrlAndFullwidthCharacter = ((ToolStripMenuItem)sender).Checked;
 
         private void PreventSmsCommandMenuItem_CheckedChanged(object sender, EventArgs e)
             => this.preventSmsCommand = ((ToolStripMenuItem)sender).Checked;
@@ -8215,7 +8220,7 @@ namespace OpenTween
 
         private void PostModeMenuItem_DropDownOpening(object sender, EventArgs e)
         {
-            this.UrlMultibyteSplitMenuItem.Checked = this.urlMultibyteSplit;
+            this.UrlMultibyteSplitMenuItem.Checked = this.SeparateUrlAndFullwidthCharacter;
             this.PreventSmsCommandMenuItem.Checked = this.preventSmsCommand;
             this.UrlAutoShortenMenuItem.Checked = this.settings.Common.UrlConvertAuto;
             this.IdeographicSpaceToSpaceMenuItem.Checked = this.settings.Common.WideSpaceConvert;
@@ -8225,7 +8230,7 @@ namespace OpenTween
 
         private void ContextMenuPostMode_Opening(object sender, CancelEventArgs e)
         {
-            this.UrlMultibyteSplitPullDownMenuItem.Checked = this.urlMultibyteSplit;
+            this.UrlMultibyteSplitPullDownMenuItem.Checked = this.SeparateUrlAndFullwidthCharacter;
             this.PreventSmsCommandPullDownMenuItem.Checked = this.preventSmsCommand;
             this.UrlAutoShortenPullDownMenuItem.Checked = this.settings.Common.UrlConvertAuto;
             this.IdeographicSpaceToSpacePullDownMenuItem.Checked = this.settings.Common.WideSpaceConvert;