OSDN Git Service

陸奥改二の一斉射に対応する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer.Test / NotificationManagerTest.cs
index 2307522..79da93f 100644 (file)
@@ -21,63 +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, _totalElapsed;\r
-            private bool _enabled;\r
-            private DateTime _start = new DateTime(2017, 11, 1);\r
-            private DateTime _now;\r
+            private DateTime _now = new DateTime(2017, 11, 1);\r
 \r
-            public MockTimer()\r
+            public DateTime GetNow()\r
             {\r
-                _now = _start;\r
-            }\r
-\r
-            public int Interval { get; set; }\r
-\r
-            public bool Enabled\r
-            {\r
-                get => _enabled;\r
-                set\r
-                {\r
-                    _enabled = value;\r
-                    _start += TimeSpan.FromMilliseconds(_elapsed);\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
-            {\r
-                Enabled = false;\r
-            }\r
-\r
-            public DateTime Now => _now;\r
-\r
-            public int Elapsed => _totalElapsed;\r
-\r
-            public void ElapseTime(int millis)\r
-            {\r
-                _totalElapsed += millis;\r
-                if (!Enabled)\r
-                {\r
-                    _now = _start += TimeSpan.FromMilliseconds(millis);\r
-                    return;\r
-                }\r
-                var after = _elapsed + millis;\r
-                for (var n = _elapsed / Interval; n < after / Interval; n++)\r
-                {\r
-                    _now = _start + TimeSpan.FromMilliseconds((n + 1) * Interval);\r
-                    Tick?.Invoke(this, EventArgs.Empty);\r
-                }\r
-                _elapsed = after;\r
-                _now = _start + TimeSpan.FromMilliseconds(_elapsed);\r
+                    var now = _now;\r
+                    _now += TimeSpan.FromSeconds(1);\r
+                    return now;\r
             }\r
         }\r
 \r
@@ -89,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
@@ -97,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
@@ -111,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
@@ -133,15 +88,16 @@ 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
+                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.Flash();\r
             manager.Enqueue("建造完了", 1, "");\r
-            timer.ElapseTime(1000);\r
+            manager.Flash();\r
             PAssert.That(() => new Message {Title = "建造が終わりました", Body = "第二ドック", Name = "建造完了"}.Equals(result));\r
         }\r
 \r
@@ -151,31 +107,36 @@ namespace KancolleSniffer.Test
         [TestMethod]\r
         public void SingleRepeatableNotification()\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
+                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 (timer.Elapsed)\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
-                        PAssert.That(() => expected.Equals(result));\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected.Repeat.Equals(result));\r
                         break;\r
                     case 4000:\r
-                        PAssert.That(() => expected.Equals(result));\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected.Repeat.Equals(result));\r
                         return;\r
                     default:\r
-                        PAssert.That(() => result == null, timer.Elapsed.ToString());\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
                         break;\r
                 }\r
                 result = null;\r
-                timer.ElapseTime(1000);\r
+                elapsed += 1000;\r
             }\r
         }\r
 \r
@@ -183,38 +144,44 @@ namespace KancolleSniffer.Test
         /// 二つの通知をリピートさせる\r
         /// </summary>\r
         [TestMethod]\r
-        public void TwoRepeatableNotofication()\r
+        public void TwoRepeatableNotification()\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
+                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 (timer.Elapsed)\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
-                        PAssert.That(() => hakuchi.Equals(result), "泊地修理2回目");\r
+                        manager.Flash();\r
+                        PAssert.That(() => hakuchi.Repeat.Equals(result), "泊地修理2回目");\r
                         break;\r
                     case 10000:\r
-                        PAssert.That(() => ensei.Equals(result), "遠征終了2回目");\r
+                        manager.Flash();\r
+                        PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\r
                         return;\r
                     default:\r
-                        PAssert.That(() => result == null, timer.Elapsed.ToString());\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
                         break;\r
                 }\r
                 result = null;\r
-                timer.ElapseTime(1000);\r
+                elapsed += 1000;\r
             }\r
         }\r
 \r
@@ -224,38 +191,45 @@ namespace KancolleSniffer.Test
         [TestMethod]\r
         public void TwoRepeatableNotification1SecDelay()\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
+                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 (timer.Elapsed)\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
-                        PAssert.That(() => ensei.Equals(result), "遠征終了2回目");\r
+                        manager.Flash();\r
+                        PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\r
                         break;\r
                     case 6000:\r
-                        PAssert.That(() => hakuchi.Equals(result), "泊地修理2回目");\r
+                        manager.Flash();\r
+                        PAssert.That(() => hakuchi.Repeat.Equals(result), "泊地修理2回目");\r
                         return;\r
                     default:\r
-                        PAssert.That(() => result == null, timer.Elapsed.ToString());\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
                         break;\r
                 }\r
                 result = null;\r
-                timer.ElapseTime(1000);\r
+                elapsed += 1000;\r
             }\r
         }\r
 \r
@@ -265,39 +239,46 @@ namespace KancolleSniffer.Test
         [TestMethod]\r
         public void RemoveRepeatableNotification()\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
+                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 (timer.Elapsed)\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
-                        PAssert.That(() => ensei.Equals(result), "遠征終了2回目");\r
+                        manager.Flash();\r
+                        PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\r
                         return;\r
                     default:\r
-                        PAssert.That(() => result == null, timer.Elapsed.ToString());\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
                         break;\r
                 }\r
                 result = null;\r
-                timer.ElapseTime(1000);\r
+                elapsed += 1000;\r
             }\r
         }\r
 \r
@@ -307,34 +288,93 @@ namespace KancolleSniffer.Test
         [TestMethod]\r
         public void SuspendRepeat()\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
+                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 (timer.Elapsed)\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
-                        PAssert.That(() => expected.Equals(result));\r
+                        manager.Flash();\r
+                        PAssert.That(() => expected.Repeat.Equals(result));\r
                         return;\r
                     default:\r
-                        PAssert.That(() => result == null, timer.Elapsed.ToString());\r
+                        manager.Flash();\r
+                        PAssert.That(() => result == null, elapsed.ToString());\r
                         break;\r
                 }\r
                 result = null;\r
-                timer.ElapseTime(1000);\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
@@ -344,37 +384,166 @@ namespace KancolleSniffer.Test
         [TestMethod]\r
         public void StopSpecificRepeatingNotification()\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
+                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 (timer.Elapsed)\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 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
-                        PAssert.That(() => expected2.Equals(result));\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
-                        PAssert.That(() => result == null, timer.Elapsed.ToString());\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
-                timer.ElapseTime(1000);\r
+                elapsed += 1000;\r
             }\r
         }\r
     }\r