OSDN Git Service

敵のスロットの搭載数を埋める
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer.Test / NotificationManagerTest.cs
index b685f31..79da93f 100644 (file)
@@ -21,45 +21,15 @@ namespace KancolleSniffer.Test
     [TestClass]\r
     public class NotificationManagerTest\r
     {\r
-        private class MockTimer : NotificationManager.ITimer\r
+        private class TimeProvider\r
         {\r
-            private int _elapsed;\r
-            private bool _enabled;\r
+            private DateTime _now = new DateTime(2017, 11, 1);\r
 \r
-            public int Interval { get; set; }\r
-\r
-            public bool Enabled\r
-            {\r
-                get => _enabled;\r
-                set\r
-                {\r
-                    _enabled = value;\r
-                    _elapsed = 0;\r
-                }\r
-            }\r
-\r
-            public event EventHandler Tick;\r
-\r
-            public void Start()\r
-            {\r
-                Enabled = true;\r
-            }\r
-\r
-            public void Stop()\r
+            public DateTime GetNow()\r
             {\r
-                Enabled = false;\r
-            }\r
-\r
-            public void ElapseTime(int millis)\r
-            {\r
-                if (!Enabled)\r
-                    return;\r
-                var after = _elapsed + millis;\r
-                for (var n = _elapsed / Interval; n < after / Interval; n++)\r
-                {\r
-                    Tick?.Invoke(this, EventArgs.Empty);\r
-                }\r
-                _elapsed = after;\r
+                    var now = _now;\r
+                    _now += TimeSpan.FromSeconds(1);\r
+                    return now;\r
             }\r
         }\r
 \r
@@ -71,6 +41,9 @@ namespace KancolleSniffer.Test
 \r
             public bool Equals(Message other) =>\r
                 other != null && Title == other.Title && Body == other.Body && Name == other.Name;\r
+\r
+            public Message Repeat => new Message {Title = "[リピート] " + Title, Body = Body, Name = Name};\r
+            public Message Cont => new Message {Title = "[継続] " + Title, Body = Body, Name = Name};\r
         }\r
 \r
         /// <summary>\r
@@ -79,12 +52,13 @@ namespace KancolleSniffer.Test
         [TestMethod]\r
         public void SingleNotification()\r
         {\r
-            var timer = new MockTimer();\r
+            var time = new TimeProvider();\r
             Message result = null;\r
             var manager =\r
-                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
-            manager.Enqueue("遠征終了", "防空射撃演習");\r
-            PAssert.That(() => new Message {Title = "遠征が終わりました", Body = "防空射撃演習", Name = "遠征終了"}.Equals(result));\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            manager.Enqueue("遠征終了", 1, "防空射撃演習");\r
+            manager.Flash();\r
+            PAssert.That(() => new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}.Equals(result));\r
         }\r
 \r
         /// <summary>\r
@@ -93,20 +67,19 @@ namespace KancolleSniffer.Test
         [TestMethod]\r
         public void TwoNotificationAtSameTime()\r
         {\r
-            var timer = new MockTimer();\r
+            var time = new TimeProvider();\r
             Message result = null;\r
             var manager =\r
-                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
-            manager.Enqueue("疲労回復40", 0, "cond40");\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            manager.Enqueue("遠征終了", 1, "防空射撃演習");\r
             manager.Enqueue("疲労回復49", 1, "cond49");\r
-            PAssert.That(() => new Message {Title = "疲労が回復しました", Body = "第一艦隊 残り9分", Name = "疲労回復"}.Equals(result));\r
+            manager.Flash();\r
+            PAssert.That(() => new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}.Equals(result));\r
             result = null;\r
-            timer.ElapseTime(1000);\r
+            manager.Flash();\r
             PAssert.That(() => result == null);\r
-            timer.ElapseTime(1000);\r
+            manager.Flash();\r
             PAssert.That(() => new Message {Title = "疲労が回復しました", Body = "第二艦隊", Name = "疲労回復"}.Equals(result));\r
-            timer.ElapseTime(2000);\r
-            PAssert.That(() => !timer.Enabled);\r
         }\r
 \r
         /// <summary>\r
@@ -115,16 +88,463 @@ namespace KancolleSniffer.Test
         [TestMethod]\r
         public void TwoNotification1SecDelay()\r
         {\r
-            var timer = new MockTimer();\r
+            var time = new TimeProvider();\r
             Message result = null;\r
             var manager =\r
-                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
-            manager.Enqueue("建造完了", "第一ドック");\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            manager.Enqueue("建造完了", 0, "");\r
+            manager.Flash();\r
             PAssert.That(() => new Message {Title = "建造が終わりました", Body = "第一ドック", Name = "建造完了"}.Equals(result));\r
-            timer.ElapseTime(1000);\r
-            manager.Enqueue("建造完了", "第二ドック");\r
-            timer.ElapseTime(1000);\r
+            manager.Flash();\r
+            manager.Enqueue("建造完了", 1, "");\r
+            manager.Flash();\r
             PAssert.That(() => new Message {Title = "建造が終わりました", Body = "第二ドック", Name = "建造完了"}.Equals(result));\r
         }\r
+\r
+        /// <summary>\r
+        /// 通知をリピートさせる\r
+        /// </summary>\r
+        [TestMethod]\r
+        public void SingleRepeatableNotification()\r
+        {\r
+            var time = new TimeProvider();\r
+            Message result = null;\r
+            var manager =\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            var expected = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
+            var elapsed = 0;\r
+            while (true)\r
+            {\r
+                switch (elapsed)\r
+                {\r
+                    case 0:\r
+                        manager.Enqueue("遠征終了", 1, "防空射撃演習", 2);\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected.Equals(result));\r
+                        break;\r
+                    case 2000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected.Repeat.Equals(result));\r
+                        break;\r
+                    case 4000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected.Repeat.Equals(result));\r
+                        return;\r
+                    default:\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
+                        break;\r
+                }\r
+                result = null;\r
+                elapsed += 1000;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// 二つの通知をリピートさせる\r
+        /// </summary>\r
+        [TestMethod]\r
+        public void TwoRepeatableNotification()\r
+        {\r
+            var time = new TimeProvider();\r
+            Message result = null;\r
+            var manager =\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
+            var hakuchi = new Message {Title = "泊地修理 第一艦隊", Body = "20分経過しました。", Name = "泊地修理20分経過"};\r
+            var elapsed = 0;\r
+            while (true)\r
+            {\r
+                switch (elapsed)\r
+                {\r
+                    case 0:\r
+                        manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
+                        manager.Flash();\r
+                        PAssert.That(() => ensei.Equals(result));\r
+                        break;\r
+                    case 2000:\r
+                        manager.Enqueue("泊地修理20分経過", 0, "", 5);\r
+                        manager.Flash();\r
+                        PAssert.That(() => hakuchi.Equals(result));\r
+                        break;\r
+                    case 7000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => hakuchi.Repeat.Equals(result), "泊地修理2回目");\r
+                        break;\r
+                    case 10000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\r
+                        return;\r
+                    default:\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
+                        break;\r
+                }\r
+                result = null;\r
+                elapsed += 1000;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// スケジュールがぶつかる二つの通知をリピートさせる\r
+        /// </summary>\r
+        [TestMethod]\r
+        public void TwoRepeatableNotification1SecDelay()\r
+        {\r
+            var time = new TimeProvider();\r
+            Message result = null;\r
+            var manager =\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
+            var hakuchi = new Message {Title = "泊地修理 第一艦隊", Body = "20分経過しました。", Name = "泊地修理20分経過"};\r
+            var elapsed = 0;\r
+            while (true)\r
+            {\r
+                switch (elapsed)\r
+                {\r
+                    case 0:\r
+                        manager.Enqueue("遠征終了", 1, "防空射撃演習", 3);\r
+                        manager.Flash();\r
+                        PAssert.That(() => ensei.Equals(result));\r
+                        break;\r
+                    case 1000:\r
+                        manager.Enqueue("泊地修理20分経過", 0, "", 2);\r
+                        manager.Flash();\r
+                        break;\r
+                    case 2000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => hakuchi.Equals(result));\r
+                        break;\r
+                    case 4000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\r
+                        break;\r
+                    case 6000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => hakuchi.Repeat.Equals(result), "泊地修理2回目");\r
+                        return;\r
+                    default:\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
+                        break;\r
+                }\r
+                result = null;\r
+                elapsed += 1000;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// リピートしている通知を止める\r
+        /// </summary>\r
+        [TestMethod]\r
+        public void RemoveRepeatableNotification()\r
+        {\r
+            var time = new TimeProvider();\r
+            Message result = null;\r
+            var manager =\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
+            var nyukyo = new Message {Title = "入渠が終わりました", Body = "第一ドック 綾波改二", Name = "入渠終了"};\r
+            var elapsed = 0;\r
+            while (true)\r
+            {\r
+                switch (elapsed)\r
+                {\r
+                    case 0:\r
+                        manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
+                        manager.Flash();\r
+                        PAssert.That(() => ensei.Equals(result));\r
+                        break;\r
+                    case 2000:\r
+                        manager.Enqueue("入渠終了", 0, "綾波改二", 5);\r
+                        manager.Flash();\r
+                        PAssert.That(() => nyukyo.Equals(result));\r
+                        break;\r
+                    case 3000:\r
+                        manager.StopRepeat("入渠終了");\r
+                        manager.Flash();\r
+                        break;\r
+                    case 7000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, "入渠終了2回目はない");\r
+                        break;\r
+                    case 10000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\r
+                        return;\r
+                    default:\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
+                        break;\r
+                }\r
+                result = null;\r
+                elapsed += 1000;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// リピートを中断・再開する\r
+        /// </summary>\r
+        [TestMethod]\r
+        public void SuspendRepeat()\r
+        {\r
+            var time = new TimeProvider();\r
+            Message result = null;\r
+            var manager =\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            var expected = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
+            var elapsed = 0;\r
+            while (true)\r
+            {\r
+                switch (elapsed)\r
+                {\r
+                    case 0:\r
+                        manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected.Equals(result));\r
+                        break;\r
+                    case 1000:\r
+                        manager.Flash();\r
+                        manager.SuspendRepeat();\r
+                        break;\r
+                    case 11000:\r
+                        manager.Flash();\r
+                        manager.ResumeRepeat();\r
+                        break;\r
+                    case 12000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected.Repeat.Equals(result));\r
+                        return;\r
+                    default:\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
+                        break;\r
+                }\r
+                result = null;\r
+                elapsed += 1000;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// リピートを例外付きで中断・再開する\r
+        /// </summary>\r
+        [TestMethod]\r
+        public void SuspendRepeatWithException()\r
+        {\r
+            var time = new TimeProvider();\r
+            Message result = null;\r
+            var manager =\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
+            var taiha = new Message {Title = "大破した艦娘がいます", Body = "摩耶改二", Name = "大破警告"};\r
+            var elapsed = 0;\r
+            while (true)\r
+            {\r
+                switch (elapsed)\r
+                {\r
+                    case 0:\r
+                        manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
+                        manager.Flash();\r
+                        PAssert.That(() => ensei.Equals(result));\r
+                        break;\r
+                    case 1000:\r
+                        manager.Flash();\r
+                        manager.SuspendRepeat("大破警告");\r
+                        break;\r
+                    case 2000:\r
+                        manager.Enqueue("大破警告", "摩耶改二", 8);\r
+                        manager.Flash();\r
+                        PAssert.That(() => taiha.Equals(result));\r
+                        break;\r
+                    case 10000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => taiha.Repeat.Equals(result));\r
+                        break;\r
+                    case 11000:\r
+                        manager.Flash();\r
+                        manager.ResumeRepeat();\r
+                        break;\r
+                    case 12000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => ensei.Repeat.Equals(result));\r
+                        return;\r
+                    default:\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
+                        break;\r
+                }\r
+                result = null;\r
+                elapsed += 1000;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// リピート中の特定の通知を止める\r
+        /// </summary>\r
+        [TestMethod]\r
+        public void StopSpecificRepeatingNotification()\r
+        {\r
+            var time = new TimeProvider();\r
+            Message result = null;\r
+            var manager =\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
+            var expected2 = new Message {Title = "遠征が終わりました", Body = "第三艦隊 海上護衛任務", Name = "遠征終了"};\r
+            var elapsed = 0;\r
+            while (true)\r
+            {\r
+                switch (elapsed)\r
+                {\r
+                    case 0:\r
+                        manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected1.Equals(result));\r
+                        break;\r
+                    case 1000:\r
+                        manager.Enqueue("遠征終了", 2, "海上護衛任務", 10);\r
+                        manager.Flash();\r
+                        break;\r
+                    case 2000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected2.Equals(result));\r
+                        break;\r
+                    case 5000:\r
+                        manager.Flash();\r
+                        manager.StopRepeat("遠征終了", 1);\r
+                        break;\r
+                    case 12000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected2.Repeat.Equals(result));\r
+                        return;\r
+                    default:\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
+                        break;\r
+                }\r
+                result = null;\r
+                elapsed += 1000;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// 継続中のリピートは艦隊やドックの番号だけ通知する\r
+        /// </summary>\r
+        [TestMethod]\r
+        public void ContinueRepeatWithoutSubject()\r
+        {\r
+            var time = new TimeProvider();\r
+            Message result = null;\r
+            var manager =\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
+            var expected2 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 ", Name = "遠征終了"};\r
+            var elapsed = 0;\r
+            while (true)\r
+            {\r
+                switch (elapsed)\r
+                {\r
+                    case 0:\r
+                        manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected1.Equals(result));\r
+                        break;\r
+                    case 2000:\r
+                        manager.Flash();\r
+                        manager.StopRepeat("遠征終了", true);\r
+                        break;\r
+                    case 10000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected2.Cont.Equals(result));\r
+                        break;\r
+                    case 11000:\r
+                        manager.Flash();\r
+                        manager.StopRepeat("遠征終了", 1);\r
+                        break;\r
+                    case 21000:\r
+                        manager.Flash();\r
+                        return;\r
+                    default:\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
+                        break;\r
+                }\r
+                result = null;\r
+                elapsed += 1000;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// 予告する\r
+        /// </summary>\r
+        [TestMethod]\r
+        public void PreliminaryNotification()\r
+        {\r
+            var time = new TimeProvider();\r
+            Message result = null;\r
+            var manager =\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            var expected = new Message {Title = "[予告] 遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
+            manager.Enqueue("遠征終了", 1, "防空射撃演習", 0, true);\r
+            manager.Flash();\r
+            PAssert.That(() => expected.Equals(result));\r
+        }\r
+\r
+        /// <summary>\r
+        /// 同時に通知されるタイトルが同じ通知をマージする\r
+        /// </summary>\r
+        [TestMethod]\r
+        public void MergeTwoNotificationsWithSameTitle()\r
+        {\r
+            var time = new TimeProvider();\r
+            Message result = null;\r
+            var manager =\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
+            manager.Enqueue("遠征終了", 2, "海上護衛任務", 10);\r
+            manager.Flash();\r
+            PAssert.That(() =>\r
+                new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習\r\n第三艦隊 海上護衛任務", Name = "遠征終了"}.Equals(result));\r
+        }\r
+\r
+        /// <summary>\r
+        /// マージされた二つの通知の一方を止める\r
+        /// </summary>\r
+        [TestMethod]\r
+        public void StopOneOfMergedNotifications()\r
+        {\r
+            var time = new TimeProvider();\r
+            Message result = null;\r
+            var manager =\r
+                new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
+            var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習\r\n第三艦隊 海上護衛任務", Name = "遠征終了"};\r
+            var expected2 = new Message {Title = "遠征が終わりました", Body = "第三艦隊 海上護衛任務", Name = "遠征終了"};\r
+            var elapsed = 0;\r
+            while (true)\r
+            {\r
+                switch (elapsed)\r
+                {\r
+                    case 0:\r
+                        manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
+                        manager.Enqueue("遠征終了", 2, "海上護衛任務", 10);\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected1.Equals(result));\r
+                        break;\r
+                    case 5000:\r
+                        manager.Flash();\r
+                        manager.StopRepeat("遠征終了", 1);\r
+                        break;\r
+                    case 10000:\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected2.Repeat.Equals(result));\r
+                        return;\r
+                    default:\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
+                        break;\r
+                }\r
+                result = null;\r
+                elapsed += 1000;\r
+            }\r
+        }\r
     }\r
 }
\ No newline at end of file