OSDN Git Service

同時に通知される通知音が同じ通知をマージする
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer.Test / NotificationManagerTest.cs
1 // Copyright (C) 2017 Kazuhiro Fujieda <fujieda@users.osdn.me>\r
2 //\r
3 // Licensed under the Apache License, Version 2.0 (the "License");\r
4 // you may not use this file except in compliance with the License.\r
5 // You may obtain a copy of the License at\r
6 //\r
7 //    http://www.apache.org/licenses/LICENSE-2.0\r
8 //\r
9 // Unless required by applicable law or agreed to in writing, software\r
10 // distributed under the License is distributed on an "AS IS" BASIS,\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
12 // See the License for the specific language governing permissions and\r
13 // limitations under the License.\r
14 \r
15 using System;\r
16 using ExpressionToCodeLib;\r
17 using Microsoft.VisualStudio.TestTools.UnitTesting;\r
18 \r
19 namespace KancolleSniffer.Test\r
20 {\r
21     [TestClass]\r
22     public class NotificationManagerTest\r
23     {\r
24         private class MockTimer : NotificationManager.ITimer\r
25         {\r
26             private int _elapsed, _totalElapsed;\r
27             private bool _enabled;\r
28             private DateTime _start = new DateTime(2017, 11, 1);\r
29             private DateTime _now;\r
30 \r
31             public MockTimer()\r
32             {\r
33                 _now = _start;\r
34             }\r
35 \r
36             public int Interval { get; set; }\r
37 \r
38             public bool Enabled\r
39             {\r
40                 get => _enabled;\r
41                 set\r
42                 {\r
43                     _enabled = value;\r
44                     _start += TimeSpan.FromMilliseconds(_elapsed);\r
45                     _elapsed = 0;\r
46                 }\r
47             }\r
48 \r
49             public event EventHandler Tick;\r
50 \r
51             public void Start()\r
52             {\r
53                 Enabled = true;\r
54             }\r
55 \r
56             public void Stop()\r
57             {\r
58                 Enabled = false;\r
59             }\r
60 \r
61             public DateTime Now => _now;\r
62 \r
63             public int Elapsed => _totalElapsed;\r
64 \r
65             public void ElapseTime(int millis)\r
66             {\r
67                 _totalElapsed += millis;\r
68                 if (!Enabled)\r
69                 {\r
70                     _now = _start += TimeSpan.FromMilliseconds(millis);\r
71                     return;\r
72                 }\r
73                 var after = _elapsed + millis;\r
74                 for (var n = _elapsed / Interval; n < after / Interval; n++)\r
75                 {\r
76                     _now = _start + TimeSpan.FromMilliseconds((n + 1) * Interval);\r
77                     Tick?.Invoke(this, EventArgs.Empty);\r
78                 }\r
79                 _elapsed = after;\r
80                 _now = _start + TimeSpan.FromMilliseconds(_elapsed);\r
81             }\r
82         }\r
83 \r
84         private class Message\r
85         {\r
86             public string Title { private get; set; }\r
87             public string Body { private get; set; }\r
88             public string Name { private get; set; }\r
89 \r
90             public bool Equals(Message other) =>\r
91                 other != null && Title == other.Title && Body == other.Body && Name == other.Name;\r
92 \r
93             public Message Repeat => new Message {Title = "[リピート] " + Title, Body = Body, Name = Name};\r
94             public Message Cont => new Message {Title = "[継続] " + Title, Body = Body, Name = Name};\r
95         }\r
96 \r
97         /// <summary>\r
98         /// 単発\r
99         /// </summary>\r
100         [TestMethod]\r
101         public void SingleNotification()\r
102         {\r
103             var timer = new MockTimer();\r
104             Message result = null;\r
105             var manager =\r
106                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
107             manager.Enqueue("遠征終了", 1, "防空射撃演習");\r
108             manager.Flash();\r
109             PAssert.That(() => new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}.Equals(result));\r
110         }\r
111 \r
112         /// <summary>\r
113         /// 連続した通知の間隔を二秒空ける\r
114         /// </summary>\r
115         [TestMethod]\r
116         public void TwoNotificationAtSameTime()\r
117         {\r
118             var timer = new MockTimer();\r
119             Message result = null;\r
120             var manager =\r
121                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
122             manager.Enqueue("遠征終了", 1, "防空射撃演習");\r
123             manager.Enqueue("疲労回復49", 1, "cond49");\r
124             manager.Flash();\r
125             PAssert.That(() => new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}.Equals(result));\r
126             result = null;\r
127             timer.ElapseTime(1000);\r
128             PAssert.That(() => result == null);\r
129             timer.ElapseTime(1000);\r
130             PAssert.That(() => new Message {Title = "疲労が回復しました", Body = "第二艦隊", Name = "疲労回復"}.Equals(result));\r
131             timer.ElapseTime(2000);\r
132             PAssert.That(() => !timer.Enabled);\r
133         }\r
134 \r
135         /// <summary>\r
136         /// 一つ目の通知の一秒後に投入された通知は一秒ずらす\r
137         /// </summary>\r
138         [TestMethod]\r
139         public void TwoNotification1SecDelay()\r
140         {\r
141             var timer = new MockTimer();\r
142             Message result = null;\r
143             var manager =\r
144                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
145             manager.Enqueue("建造完了", 0, "");\r
146             manager.Flash();\r
147             PAssert.That(() => new Message {Title = "建造が終わりました", Body = "第一ドック", Name = "建造完了"}.Equals(result));\r
148             timer.ElapseTime(1000);\r
149             manager.Enqueue("建造完了", 1, "");\r
150             manager.Flash();\r
151             timer.ElapseTime(1000);\r
152             PAssert.That(() => new Message {Title = "建造が終わりました", Body = "第二ドック", Name = "建造完了"}.Equals(result));\r
153         }\r
154 \r
155         /// <summary>\r
156         /// 通知をリピートさせる\r
157         /// </summary>\r
158         [TestMethod]\r
159         public void SingleRepeatableNotification()\r
160         {\r
161             var timer = new MockTimer();\r
162             Message result = null;\r
163             var manager =\r
164                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
165             var expected = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
166             while (true)\r
167             {\r
168                 switch (timer.Elapsed)\r
169                 {\r
170                     case 0:\r
171                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 2);\r
172                         manager.Flash();\r
173                         PAssert.That(() => expected.Equals(result));\r
174                         break;\r
175                     case 2000:\r
176                         PAssert.That(() => expected.Repeat.Equals(result));\r
177                         break;\r
178                     case 4000:\r
179                         PAssert.That(() => expected.Repeat.Equals(result));\r
180                         return;\r
181                     default:\r
182                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
183                         break;\r
184                 }\r
185                 result = null;\r
186                 timer.ElapseTime(1000);\r
187             }\r
188         }\r
189 \r
190         /// <summary>\r
191         /// 二つの通知をリピートさせる\r
192         /// </summary>\r
193         [TestMethod]\r
194         public void TwoRepeatableNotofication()\r
195         {\r
196             var timer = new MockTimer();\r
197             Message result = null;\r
198             var manager =\r
199                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
200             var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
201             var hakuchi = new Message {Title = "泊地修理 第一艦隊", Body = "20分経過しました。", Name = "泊地修理20分経過"};\r
202             while (true)\r
203             {\r
204                 switch (timer.Elapsed)\r
205                 {\r
206                     case 0:\r
207                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
208                         manager.Flash();\r
209                         PAssert.That(() => ensei.Equals(result));\r
210                         break;\r
211                     case 2000:\r
212                         manager.Enqueue("泊地修理20分経過", 0, "", 5);\r
213                         manager.Flash();\r
214                         PAssert.That(() => hakuchi.Equals(result));\r
215                         break;\r
216                     case 7000:\r
217                         PAssert.That(() => hakuchi.Repeat.Equals(result), "泊地修理2回目");\r
218                         break;\r
219                     case 10000:\r
220                         PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\r
221                         return;\r
222                     default:\r
223                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
224                         break;\r
225                 }\r
226                 result = null;\r
227                 timer.ElapseTime(1000);\r
228             }\r
229         }\r
230 \r
231         /// <summary>\r
232         /// スケジュールがぶつかる二つの通知をリピートさせる\r
233         /// </summary>\r
234         [TestMethod]\r
235         public void TwoRepeatableNotification1SecDelay()\r
236         {\r
237             var timer = new MockTimer();\r
238             Message result = null;\r
239             var manager =\r
240                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
241             var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
242             var hakuchi = new Message {Title = "泊地修理 第一艦隊", Body = "20分経過しました。", Name = "泊地修理20分経過"};\r
243             while (true)\r
244             {\r
245                 switch (timer.Elapsed)\r
246                 {\r
247                     case 0:\r
248                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 3);\r
249                         manager.Flash();\r
250                         PAssert.That(() => ensei.Equals(result));\r
251                         break;\r
252                     case 1000:\r
253                         manager.Enqueue("泊地修理20分経過", 0, "", 2);\r
254                         manager.Flash();\r
255                         break;\r
256                     case 2000:\r
257                         PAssert.That(() => hakuchi.Equals(result));\r
258                         break;\r
259                     case 4000:\r
260                         PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\r
261                         break;\r
262                     case 6000:\r
263                         PAssert.That(() => hakuchi.Repeat.Equals(result), "泊地修理2回目");\r
264                         return;\r
265                     default:\r
266                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
267                         break;\r
268                 }\r
269                 result = null;\r
270                 timer.ElapseTime(1000);\r
271             }\r
272         }\r
273 \r
274         /// <summary>\r
275         /// リピートしている通知を止める\r
276         /// </summary>\r
277         [TestMethod]\r
278         public void RemoveRepeatableNotification()\r
279         {\r
280             var timer = new MockTimer();\r
281             Message result = null;\r
282             var manager =\r
283                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
284             var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
285             var nyukyo = new Message {Title = "入渠が終わりました", Body = "第一ドック 綾波改二", Name = "入渠終了"};\r
286             while (true)\r
287             {\r
288                 switch (timer.Elapsed)\r
289                 {\r
290                     case 0:\r
291                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
292                         manager.Flash();\r
293                         PAssert.That(() => ensei.Equals(result));\r
294                         break;\r
295                     case 2000:\r
296                         manager.Enqueue("入渠終了", 0, "綾波改二", 5);\r
297                         manager.Flash();\r
298                         PAssert.That(() => nyukyo.Equals(result));\r
299                         break;\r
300                     case 3000:\r
301                         manager.StopRepeat("入渠終了");\r
302                         break;\r
303                     case 7000:\r
304                         PAssert.That(() => result == null, "入渠終了2回目はない");\r
305                         break;\r
306                     case 10000:\r
307                         PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\r
308                         return;\r
309                     default:\r
310                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
311                         break;\r
312                 }\r
313                 result = null;\r
314                 timer.ElapseTime(1000);\r
315             }\r
316         }\r
317 \r
318         /// <summary>\r
319         /// リピートを中断・再開する\r
320         /// </summary>\r
321         [TestMethod]\r
322         public void SuspendRepeat()\r
323         {\r
324             var timer = new MockTimer();\r
325             Message result = null;\r
326             var manager =\r
327                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
328             var expected = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
329             while (true)\r
330             {\r
331                 switch (timer.Elapsed)\r
332                 {\r
333                     case 0:\r
334                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
335                         manager.Flash();\r
336                         PAssert.That(() => expected.Equals(result));\r
337                         break;\r
338                     case 1000:\r
339                         manager.SuspendRepeat();\r
340                         break;\r
341                     case 11000:\r
342                         manager.ResumeRepeat();\r
343                         break;\r
344                     case 12000:\r
345                         PAssert.That(() => expected.Repeat.Equals(result));\r
346                         return;\r
347                     default:\r
348                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
349                         break;\r
350                 }\r
351                 result = null;\r
352                 timer.ElapseTime(1000);\r
353             }\r
354         }\r
355 \r
356         /// <summary>\r
357         /// リピート中の特定の通知を止める\r
358         /// </summary>\r
359         [TestMethod]\r
360         public void StopSpecificRepeatingNotification()\r
361         {\r
362             var timer = new MockTimer();\r
363             Message result = null;\r
364             var manager =\r
365                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
366             var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
367             var expected2 = new Message {Title = "遠征が終わりました", Body = "第三艦隊 海上護衛任務", Name = "遠征終了"};\r
368             while (true)\r
369             {\r
370                 switch (timer.Elapsed)\r
371                 {\r
372                     case 0:\r
373                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
374                         manager.Flash();\r
375                         PAssert.That(() => expected1.Equals(result));\r
376                         break;\r
377                     case 1000:\r
378                         manager.Enqueue("遠征終了", 2, "海上護衛任務", 10);\r
379                         manager.Flash();\r
380                         break;\r
381                     case 2000:\r
382                         PAssert.That(() => expected2.Equals(result));\r
383                         break;\r
384                     case 5000:\r
385                         manager.StopRepeat("遠征終了", 1);\r
386                         break;\r
387                     case 12000:\r
388                         PAssert.That(() => expected2.Repeat.Equals(result));\r
389                         return;\r
390                     default:\r
391                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
392                         break;\r
393                 }\r
394                 result = null;\r
395                 timer.ElapseTime(1000);\r
396             }\r
397         }\r
398 \r
399         /// <summary>\r
400         /// 継続中のリピートは艦隊やドックの番号だけ通知する\r
401         /// </summary>\r
402         [TestMethod]\r
403         public void ContinueRepeatWithoutSubject()\r
404         {\r
405             var timer = new MockTimer();\r
406             Message result = null;\r
407             var manager =\r
408                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
409             var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
410             var expected2 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 ", Name = "遠征終了"};\r
411             while (true)\r
412             {\r
413                 switch (timer.Elapsed)\r
414                 {\r
415                     case 0:\r
416                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
417                         manager.Flash();\r
418                         PAssert.That(() => expected1.Equals(result));\r
419                         break;\r
420                     case 2000:\r
421                         manager.StopRepeat("遠征終了", true);\r
422                         break;\r
423                     case 10000:\r
424                         PAssert.That(() => expected2.Cont.Equals(result));\r
425                         break;\r
426                     case 11000:\r
427                         manager.StopRepeat("遠征終了", 1);\r
428                         break;\r
429                     case 21000:\r
430                         return;\r
431                     default:\r
432                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
433                         break;\r
434                 }\r
435                 result = null;\r
436                 timer.ElapseTime(1000);\r
437             }\r
438         }\r
439 \r
440         /// <summary>\r
441         /// 予告する\r
442         /// </summary>\r
443         [TestMethod]\r
444         public void PreliminaryNotification()\r
445         {\r
446             var timer = new MockTimer();\r
447             Message result = null;\r
448             var manager =\r
449                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
450             var expected = new Message {Title = "[予告] 遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
451             manager.Enqueue("遠征終了", 1, "防空射撃演習", 0, true);\r
452             manager.Flash();\r
453             PAssert.That(() => expected.Equals(result));\r
454         }\r
455 \r
456         /// <summary>\r
457         /// 同時に通知されるタイトルが同じ通知をマージする\r
458         /// </summary>\r
459         [TestMethod]\r
460         public void MergeTwoNotificationsWithSameTitle()\r
461         {\r
462             var timer = new MockTimer();\r
463             Message result = null;\r
464             var manager =\r
465                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
466             manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
467             manager.Enqueue("遠征終了", 2, "海上護衛任務", 10);\r
468             manager.Flash();\r
469             PAssert.That(() =>\r
470                 new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習\r\n第三艦隊 海上護衛任務", Name = "遠征終了"}.Equals(result));\r
471         }\r
472 \r
473         /// <summary>\r
474         /// マージされた二つの通知の一方を止める\r
475         /// </summary>\r
476         [TestMethod]\r
477         public void StopOneOfMergedNotifications()\r
478         {\r
479             var timer = new MockTimer();\r
480             Message result = null;\r
481             var manager =\r
482                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
483             var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習\r\n第三艦隊 海上護衛任務", Name = "遠征終了"};\r
484             var expected2 = new Message {Title = "遠征が終わりました", Body = "第三艦隊 海上護衛任務", Name = "遠征終了"};\r
485             while (true)\r
486             {\r
487                 switch (timer.Elapsed)\r
488                 {\r
489                     case 0:\r
490                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
491                         manager.Enqueue("遠征終了", 2, "海上護衛任務", 10);\r
492                         manager.Flash();\r
493                         PAssert.That(() => expected1.Equals(result));\r
494                         break;\r
495                     case 5000:\r
496                         manager.StopRepeat("遠征終了", 1);\r
497                         break;\r
498                     case 10000:\r
499                         PAssert.That(() => expected2.Repeat.Equals(result));\r
500                         return;\r
501                     default:\r
502                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
503                         break;\r
504                 }\r
505                 result = null;\r
506                 timer.ElapseTime(1000);\r
507             }\r
508         }\r
509     }\r
510 }