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 KancolleSniffer.Notification;\r
18 using Microsoft.VisualStudio.TestTools.UnitTesting;\r
19 \r
20 namespace KancolleSniffer.Test\r
21 {\r
22     [TestClass]\r
23     public class NotificationManagerTest\r
24     {\r
25         private class TimeProvider\r
26         {\r
27             private DateTime _now = new DateTime(2017, 11, 1);\r
28 \r
29             public DateTime GetNow()\r
30             {\r
31                     var now = _now;\r
32                     _now += TimeSpan.FromSeconds(1);\r
33                     return now;\r
34             }\r
35         }\r
36 \r
37         private class Message\r
38         {\r
39             public string Title { private get; set; }\r
40             public string Body { private get; set; }\r
41             public string Name { private get; set; }\r
42 \r
43             public bool Equals(Message other) =>\r
44                 other != null && Title == other.Title && Body == other.Body && Name == other.Name;\r
45 \r
46             public Message Repeat => new Message {Title = "[リピート] " + Title, Body = Body, Name = Name};\r
47             public Message Cont => new Message {Title = "[継続] " + Title, Body = Body, Name = Name};\r
48         }\r
49 \r
50         /// <summary>\r
51         /// 単発\r
52         /// </summary>\r
53         [TestMethod]\r
54         public void SingleNotification()\r
55         {\r
56             var time = new TimeProvider();\r
57             Message result = null;\r
58             var manager =\r
59                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
60             manager.Enqueue("遠征終了", 1, "防空射撃演習");\r
61             manager.Flush();\r
62             PAssert.That(() => new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}.Equals(result));\r
63         }\r
64 \r
65         /// <summary>\r
66         /// 連続した通知の間隔を二秒空ける\r
67         /// </summary>\r
68         [TestMethod]\r
69         public void TwoNotificationAtSameTime()\r
70         {\r
71             var time = new TimeProvider();\r
72             Message result = null;\r
73             var manager =\r
74                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
75             manager.Enqueue("遠征終了", 1, "防空射撃演習");\r
76             manager.Enqueue("疲労回復49", 1, "cond49");\r
77             manager.Flush();\r
78             PAssert.That(() => new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}.Equals(result));\r
79             result = null;\r
80             manager.Flush();\r
81             PAssert.That(() => result == null);\r
82             manager.Flush();\r
83             PAssert.That(() => new Message {Title = "疲労が回復しました", Body = "第二艦隊", Name = "疲労回復"}.Equals(result));\r
84         }\r
85 \r
86         /// <summary>\r
87         /// 一つ目の通知の一秒後に投入された通知は一秒ずらす\r
88         /// </summary>\r
89         [TestMethod]\r
90         public void TwoNotification1SecDelay()\r
91         {\r
92             var time = new TimeProvider();\r
93             Message result = null;\r
94             var manager =\r
95                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
96             manager.Enqueue("建造完了", 0, "");\r
97             manager.Flush();\r
98             PAssert.That(() => new Message {Title = "建造が終わりました", Body = "第一ドック", Name = "建造完了"}.Equals(result));\r
99             manager.Flush();\r
100             manager.Enqueue("建造完了", 1, "");\r
101             manager.Flush();\r
102             PAssert.That(() => new Message {Title = "建造が終わりました", Body = "第二ドック", Name = "建造完了"}.Equals(result));\r
103         }\r
104 \r
105         /// <summary>\r
106         /// 通知をリピートさせる\r
107         /// </summary>\r
108         [TestMethod]\r
109         public void SingleRepeatableNotification()\r
110         {\r
111             var time = new TimeProvider();\r
112             Message result = null;\r
113             var manager =\r
114                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
115             var expected = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
116             var elapsed = 0;\r
117             while (true)\r
118             {\r
119                 switch (elapsed)\r
120                 {\r
121                     case 0:\r
122                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 2);\r
123                         manager.Flush();\r
124                         PAssert.That(() => expected.Equals(result));\r
125                         break;\r
126                     case 2000:\r
127                         manager.Flush();\r
128                         PAssert.That(() => expected.Repeat.Equals(result));\r
129                         break;\r
130                     case 4000:\r
131                         manager.Flush();\r
132                         PAssert.That(() => expected.Repeat.Equals(result));\r
133                         return;\r
134                     default:\r
135                         manager.Flush();\r
136                         PAssert.That(() => result == null, elapsed.ToString());\r
137                         break;\r
138                 }\r
139                 result = null;\r
140                 elapsed += 1000;\r
141             }\r
142         }\r
143 \r
144         /// <summary>\r
145         /// 二つの通知をリピートさせる\r
146         /// </summary>\r
147         [TestMethod]\r
148         public void TwoRepeatableNotification()\r
149         {\r
150             var time = new TimeProvider();\r
151             Message result = null;\r
152             var manager =\r
153                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
154             var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
155             var hakuchi = new Message {Title = "泊地修理 第一艦隊", Body = "20分経過しました。", Name = "泊地修理20分経過"};\r
156             var elapsed = 0;\r
157             while (true)\r
158             {\r
159                 switch (elapsed)\r
160                 {\r
161                     case 0:\r
162                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
163                         manager.Flush();\r
164                         PAssert.That(() => ensei.Equals(result));\r
165                         break;\r
166                     case 2000:\r
167                         manager.Enqueue("泊地修理20分経過", 0, "", 5);\r
168                         manager.Flush();\r
169                         PAssert.That(() => hakuchi.Equals(result));\r
170                         break;\r
171                     case 7000:\r
172                         manager.Flush();\r
173                         PAssert.That(() => hakuchi.Repeat.Equals(result), "泊地修理2回目");\r
174                         break;\r
175                     case 10000:\r
176                         manager.Flush();\r
177                         PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\r
178                         return;\r
179                     default:\r
180                         manager.Flush();\r
181                         PAssert.That(() => result == null, elapsed.ToString());\r
182                         break;\r
183                 }\r
184                 result = null;\r
185                 elapsed += 1000;\r
186             }\r
187         }\r
188 \r
189         /// <summary>\r
190         /// スケジュールがぶつかる二つの通知をリピートさせる\r
191         /// </summary>\r
192         [TestMethod]\r
193         public void TwoRepeatableNotification1SecDelay()\r
194         {\r
195             var time = new TimeProvider();\r
196             Message result = null;\r
197             var manager =\r
198                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
199             var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
200             var hakuchi = new Message {Title = "泊地修理 第一艦隊", Body = "20分経過しました。", Name = "泊地修理20分経過"};\r
201             var elapsed = 0;\r
202             while (true)\r
203             {\r
204                 switch (elapsed)\r
205                 {\r
206                     case 0:\r
207                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 3);\r
208                         manager.Flush();\r
209                         PAssert.That(() => ensei.Equals(result));\r
210                         break;\r
211                     case 1000:\r
212                         manager.Enqueue("泊地修理20分経過", 0, "", 2);\r
213                         manager.Flush();\r
214                         break;\r
215                     case 2000:\r
216                         manager.Flush();\r
217                         PAssert.That(() => hakuchi.Equals(result));\r
218                         break;\r
219                     case 4000:\r
220                         manager.Flush();\r
221                         PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\r
222                         break;\r
223                     case 6000:\r
224                         manager.Flush();\r
225                         PAssert.That(() => hakuchi.Repeat.Equals(result), "泊地修理2回目");\r
226                         return;\r
227                     default:\r
228                         manager.Flush();\r
229                         PAssert.That(() => result == null, elapsed.ToString());\r
230                         break;\r
231                 }\r
232                 result = null;\r
233                 elapsed += 1000;\r
234             }\r
235         }\r
236 \r
237         /// <summary>\r
238         /// リピートしている通知を止める\r
239         /// </summary>\r
240         [TestMethod]\r
241         public void RemoveRepeatableNotification()\r
242         {\r
243             var time = new TimeProvider();\r
244             Message result = null;\r
245             var manager =\r
246                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
247             var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
248             var nyukyo = new Message {Title = "入渠が終わりました", Body = "第一ドック 綾波改二", Name = "入渠終了"};\r
249             var elapsed = 0;\r
250             while (true)\r
251             {\r
252                 switch (elapsed)\r
253                 {\r
254                     case 0:\r
255                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
256                         manager.Flush();\r
257                         PAssert.That(() => ensei.Equals(result));\r
258                         break;\r
259                     case 2000:\r
260                         manager.Enqueue("入渠終了", 0, "綾波改二", 5);\r
261                         manager.Flush();\r
262                         PAssert.That(() => nyukyo.Equals(result));\r
263                         break;\r
264                     case 3000:\r
265                         manager.StopRepeat("入渠終了");\r
266                         manager.Flush();\r
267                         break;\r
268                     case 7000:\r
269                         manager.Flush();\r
270                         PAssert.That(() => result == null, "入渠終了2回目はない");\r
271                         break;\r
272                     case 10000:\r
273                         manager.Flush();\r
274                         PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\r
275                         return;\r
276                     default:\r
277                         manager.Flush();\r
278                         PAssert.That(() => result == null, elapsed.ToString());\r
279                         break;\r
280                 }\r
281                 result = null;\r
282                 elapsed += 1000;\r
283             }\r
284         }\r
285 \r
286         /// <summary>\r
287         /// リピートを中断・再開する\r
288         /// </summary>\r
289         [TestMethod]\r
290         public void SuspendRepeat()\r
291         {\r
292             var time = new TimeProvider();\r
293             Message result = null;\r
294             var manager =\r
295                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
296             var expected = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
297             var elapsed = 0;\r
298             while (true)\r
299             {\r
300                 switch (elapsed)\r
301                 {\r
302                     case 0:\r
303                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
304                         manager.Flush();\r
305                         PAssert.That(() => expected.Equals(result));\r
306                         break;\r
307                     case 1000:\r
308                         manager.Flush();\r
309                         manager.SuspendRepeat();\r
310                         break;\r
311                     case 11000:\r
312                         manager.Flush();\r
313                         manager.ResumeRepeat();\r
314                         break;\r
315                     case 12000:\r
316                         manager.Flush();\r
317                         PAssert.That(() => expected.Repeat.Equals(result));\r
318                         return;\r
319                     default:\r
320                         manager.Flush();\r
321                         PAssert.That(() => result == null, elapsed.ToString());\r
322                         break;\r
323                 }\r
324                 result = null;\r
325                 elapsed += 1000;\r
326             }\r
327         }\r
328 \r
329         /// <summary>\r
330         /// リピートを例外付きで中断・再開する\r
331         /// </summary>\r
332         [TestMethod]\r
333         public void SuspendRepeatWithException()\r
334         {\r
335             var time = new TimeProvider();\r
336             Message result = null;\r
337             var manager =\r
338                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
339             var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
340             var taiha = new Message {Title = "大破した艦娘がいます", Body = "摩耶改二", Name = "大破警告"};\r
341             var elapsed = 0;\r
342             while (true)\r
343             {\r
344                 switch (elapsed)\r
345                 {\r
346                     case 0:\r
347                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
348                         manager.Flush();\r
349                         PAssert.That(() => ensei.Equals(result));\r
350                         break;\r
351                     case 1000:\r
352                         manager.Flush();\r
353                         manager.SuspendRepeat("大破警告");\r
354                         break;\r
355                     case 2000:\r
356                         manager.Enqueue("大破警告", "摩耶改二", 8);\r
357                         manager.Flush();\r
358                         PAssert.That(() => taiha.Equals(result));\r
359                         break;\r
360                     case 10000:\r
361                         manager.Flush();\r
362                         PAssert.That(() => taiha.Repeat.Equals(result));\r
363                         break;\r
364                     case 11000:\r
365                         manager.Flush();\r
366                         manager.ResumeRepeat();\r
367                         break;\r
368                     case 12000:\r
369                         manager.Flush();\r
370                         PAssert.That(() => ensei.Repeat.Equals(result));\r
371                         return;\r
372                     default:\r
373                         manager.Flush();\r
374                         PAssert.That(() => result == null, elapsed.ToString());\r
375                         break;\r
376                 }\r
377                 result = null;\r
378                 elapsed += 1000;\r
379             }\r
380         }\r
381 \r
382         /// <summary>\r
383         /// リピート中の特定の通知を止める\r
384         /// </summary>\r
385         [TestMethod]\r
386         public void StopSpecificRepeatingNotification()\r
387         {\r
388             var time = new TimeProvider();\r
389             Message result = null;\r
390             var manager =\r
391                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
392             var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
393             var expected2 = new Message {Title = "遠征が終わりました", Body = "第三艦隊 海上護衛任務", Name = "遠征終了"};\r
394             var elapsed = 0;\r
395             while (true)\r
396             {\r
397                 switch (elapsed)\r
398                 {\r
399                     case 0:\r
400                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
401                         manager.Flush();\r
402                         PAssert.That(() => expected1.Equals(result));\r
403                         break;\r
404                     case 1000:\r
405                         manager.Enqueue("遠征終了", 2, "海上護衛任務", 10);\r
406                         manager.Flush();\r
407                         break;\r
408                     case 2000:\r
409                         manager.Flush();\r
410                         PAssert.That(() => expected2.Equals(result));\r
411                         break;\r
412                     case 5000:\r
413                         manager.Flush();\r
414                         manager.StopRepeat("遠征終了", 1);\r
415                         break;\r
416                     case 12000:\r
417                         manager.Flush();\r
418                         PAssert.That(() => expected2.Repeat.Equals(result));\r
419                         return;\r
420                     default:\r
421                         manager.Flush();\r
422                         PAssert.That(() => result == null, elapsed.ToString());\r
423                         break;\r
424                 }\r
425                 result = null;\r
426                 elapsed += 1000;\r
427             }\r
428         }\r
429 \r
430         /// <summary>\r
431         /// 継続中のリピートは艦隊やドックの番号だけ通知する\r
432         /// </summary>\r
433         [TestMethod]\r
434         public void ContinueRepeatWithoutSubject()\r
435         {\r
436             var time = new TimeProvider();\r
437             Message result = null;\r
438             var manager =\r
439                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
440             var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
441             var expected2 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 ", Name = "遠征終了"};\r
442             var elapsed = 0;\r
443             while (true)\r
444             {\r
445                 switch (elapsed)\r
446                 {\r
447                     case 0:\r
448                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
449                         manager.Flush();\r
450                         PAssert.That(() => expected1.Equals(result));\r
451                         break;\r
452                     case 2000:\r
453                         manager.Flush();\r
454                         manager.StopRepeat("遠征終了", true);\r
455                         break;\r
456                     case 10000:\r
457                         manager.Flush();\r
458                         PAssert.That(() => expected2.Cont.Equals(result));\r
459                         break;\r
460                     case 11000:\r
461                         manager.Flush();\r
462                         manager.StopRepeat("遠征終了", 1);\r
463                         break;\r
464                     case 21000:\r
465                         manager.Flush();\r
466                         return;\r
467                     default:\r
468                         manager.Flush();\r
469                         PAssert.That(() => result == null, elapsed.ToString());\r
470                         break;\r
471                 }\r
472                 result = null;\r
473                 elapsed += 1000;\r
474             }\r
475         }\r
476 \r
477         /// <summary>\r
478         /// 予告する\r
479         /// </summary>\r
480         [TestMethod]\r
481         public void PreliminaryNotification()\r
482         {\r
483             var time = new TimeProvider();\r
484             Message result = null;\r
485             var manager =\r
486                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
487             var expected = new Message {Title = "[予告] 遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
488             manager.Enqueue("遠征終了", 1, "防空射撃演習", 0, true);\r
489             manager.Flush();\r
490             PAssert.That(() => expected.Equals(result));\r
491         }\r
492 \r
493         /// <summary>\r
494         /// 同時に通知されるタイトルが同じ通知をマージする\r
495         /// </summary>\r
496         [TestMethod]\r
497         public void MergeTwoNotificationsWithSameTitle()\r
498         {\r
499             var time = new TimeProvider();\r
500             Message result = null;\r
501             var manager =\r
502                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
503             manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
504             manager.Enqueue("遠征終了", 2, "海上護衛任務", 10);\r
505             manager.Flush();\r
506             PAssert.That(() =>\r
507                 new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習\r\n第三艦隊 海上護衛任務", Name = "遠征終了"}.Equals(result));\r
508         }\r
509 \r
510         /// <summary>\r
511         /// マージされた二つの通知の一方を止める\r
512         /// </summary>\r
513         [TestMethod]\r
514         public void StopOneOfMergedNotifications()\r
515         {\r
516             var time = new TimeProvider();\r
517             Message result = null;\r
518             var manager =\r
519                 new Scheduler((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow);\r
520             var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習\r\n第三艦隊 海上護衛任務", Name = "遠征終了"};\r
521             var expected2 = new Message {Title = "遠征が終わりました", Body = "第三艦隊 海上護衛任務", Name = "遠征終了"};\r
522             var elapsed = 0;\r
523             while (true)\r
524             {\r
525                 switch (elapsed)\r
526                 {\r
527                     case 0:\r
528                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
529                         manager.Enqueue("遠征終了", 2, "海上護衛任務", 10);\r
530                         manager.Flush();\r
531                         PAssert.That(() => expected1.Equals(result));\r
532                         break;\r
533                     case 5000:\r
534                         manager.Flush();\r
535                         manager.StopRepeat("遠征終了", 1);\r
536                         break;\r
537                     case 10000:\r
538                         manager.Flush();\r
539                         PAssert.That(() => expected2.Repeat.Equals(result));\r
540                         return;\r
541                     default:\r
542                         manager.Flush();\r
543                         PAssert.That(() => result == null, elapsed.ToString());\r
544                         break;\r
545                 }\r
546                 result = null;\r
547                 elapsed += 1000;\r
548             }\r
549         }\r
550     }\r
551 }