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 \r
94         /// <summary>\r
95         /// 単発\r
96         /// </summary>\r
97         [TestMethod]\r
98         public void SingleNotification()\r
99         {\r
100             var timer = new MockTimer();\r
101             Message result = null;\r
102             var manager =\r
103                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
104             manager.Enqueue("遠征終了", "防空射撃演習");\r
105             PAssert.That(() => new Message {Title = "遠征が終わりました", Body = "第一艦隊 防空射撃演習", Name = "遠征終了"}.Equals(result));\r
106         }\r
107 \r
108         /// <summary>\r
109         /// 連続した通知の間隔を二秒空ける\r
110         /// </summary>\r
111         [TestMethod]\r
112         public void TwoNotificationAtSameTime()\r
113         {\r
114             var timer = new MockTimer();\r
115             Message result = null;\r
116             var manager =\r
117                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
118             manager.Enqueue("疲労回復40", 0, "cond40");\r
119             manager.Enqueue("疲労回復49", 1, "cond49");\r
120             PAssert.That(() => new Message {Title = "疲労が回復しました", Body = "第一艦隊 残り9分", Name = "疲労回復"}.Equals(result));\r
121             result = null;\r
122             timer.ElapseTime(1000);\r
123             PAssert.That(() => result == null);\r
124             timer.ElapseTime(1000);\r
125             PAssert.That(() => new Message {Title = "疲労が回復しました", Body = "第二艦隊", Name = "疲労回復"}.Equals(result));\r
126             timer.ElapseTime(2000);\r
127             PAssert.That(() => !timer.Enabled);\r
128         }\r
129 \r
130         /// <summary>\r
131         /// 一つ目の通知の一秒後に投入された通知は一秒ずらす\r
132         /// </summary>\r
133         [TestMethod]\r
134         public void TwoNotification1SecDelay()\r
135         {\r
136             var timer = new MockTimer();\r
137             Message result = null;\r
138             var manager =\r
139                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
140             manager.Enqueue("建造完了", 0, "");\r
141             PAssert.That(() => new Message {Title = "建造が終わりました", Body = "第一ドック", Name = "建造完了"}.Equals(result));\r
142             timer.ElapseTime(1000);\r
143             manager.Enqueue("建造完了", 1, "");\r
144             timer.ElapseTime(1000);\r
145             PAssert.That(() => new Message {Title = "建造が終わりました", Body = "第二ドック", Name = "建造完了"}.Equals(result));\r
146         }\r
147 \r
148         /// <summary>\r
149         /// 通知をリピートさせる\r
150         /// </summary>\r
151         [TestMethod]\r
152         public void SingleRepeatableNotification()\r
153         {\r
154             var timer = new MockTimer();\r
155             Message result = null;\r
156             var manager =\r
157                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
158             var expected = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
159             while (true)\r
160             {\r
161                 switch (timer.Elapsed)\r
162                 {\r
163                     case 0:\r
164                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 2);\r
165                         PAssert.That(() => expected.Equals(result));\r
166                         break;\r
167                     case 2000:\r
168                         PAssert.That(() => expected.Equals(result));\r
169                         break;\r
170                     case 4000:\r
171                         PAssert.That(() => expected.Equals(result));\r
172                         return;\r
173                     default:\r
174                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
175                         break;\r
176                 }\r
177                 result = null;\r
178                 timer.ElapseTime(1000);\r
179             }\r
180         }\r
181 \r
182         /// <summary>\r
183         /// 二つの通知をリピートさせる\r
184         /// </summary>\r
185         [TestMethod]\r
186         public void TwoRepeatableNotofication()\r
187         {\r
188             var timer = new MockTimer();\r
189             Message result = null;\r
190             var manager =\r
191                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
192             var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
193             var hakuchi = new Message {Title = "泊地修理 第一艦隊", Body = "20分経過しました。", Name = "泊地修理20分経過"};\r
194             while (true)\r
195             {\r
196                 switch (timer.Elapsed)\r
197                 {\r
198                     case 0:\r
199                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
200                         PAssert.That(() => ensei.Equals(result));\r
201                         break;\r
202                     case 2000:\r
203                         manager.Enqueue("泊地修理20分経過", 0, "", 5);\r
204                         PAssert.That(() => hakuchi.Equals(result));\r
205                         break;\r
206                     case 7000:\r
207                         PAssert.That(() => hakuchi.Equals(result), "泊地修理2回目");\r
208                         break;\r
209                     case 10000:\r
210                         PAssert.That(() => ensei.Equals(result), "遠征終了2回目");\r
211                         return;\r
212                     default:\r
213                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
214                         break;\r
215                 }\r
216                 result = null;\r
217                 timer.ElapseTime(1000);\r
218             }\r
219         }\r
220 \r
221         /// <summary>\r
222         /// スケジュールがぶつかる二つの通知をリピートさせる\r
223         /// </summary>\r
224         [TestMethod]\r
225         public void TwoRepeatableNotification1SecDelay()\r
226         {\r
227             var timer = new MockTimer();\r
228             Message result = null;\r
229             var manager =\r
230                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
231             var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
232             var hakuchi = new Message {Title = "泊地修理 第一艦隊", Body = "20分経過しました。", Name = "泊地修理20分経過"};\r
233             while (true)\r
234             {\r
235                 switch (timer.Elapsed)\r
236                 {\r
237                     case 0:\r
238                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 3);\r
239                         PAssert.That(() => ensei.Equals(result));\r
240                         break;\r
241                     case 1000:\r
242                         manager.Enqueue("泊地修理20分経過", 0, "", 2);\r
243                         break;\r
244                     case 2000:\r
245                         PAssert.That(() => hakuchi.Equals(result));\r
246                         break;\r
247                     case 4000:\r
248                         PAssert.That(() => ensei.Equals(result), "遠征終了2回目");\r
249                         break;\r
250                     case 6000:\r
251                         PAssert.That(() => hakuchi.Equals(result), "泊地修理2回目");\r
252                         return;\r
253                     default:\r
254                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
255                         break;\r
256                 }\r
257                 result = null;\r
258                 timer.ElapseTime(1000);\r
259             }\r
260         }\r
261 \r
262         /// <summary>\r
263         /// リピートしている通知を止める\r
264         /// </summary>\r
265         [TestMethod]\r
266         public void RemoveRepeatableNotification()\r
267         {\r
268             var timer = new MockTimer();\r
269             Message result = null;\r
270             var manager =\r
271                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
272             var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
273             var nyukyo = new Message {Title = "入渠が終わりました", Body = "第一ドック 綾波改二", Name = "入渠終了"};\r
274             while (true)\r
275             {\r
276                 switch (timer.Elapsed)\r
277                 {\r
278                     case 0:\r
279                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
280                         PAssert.That(() => ensei.Equals(result));\r
281                         break;\r
282                     case 2000:\r
283                         manager.Enqueue("入渠終了", 0, "綾波改二", 5);\r
284                         PAssert.That(() => nyukyo.Equals(result));\r
285                         break;\r
286                     case 3000:\r
287                         manager.StopRepeat("入渠終了");\r
288                         break;\r
289                     case 7000:\r
290                         PAssert.That(() => result == null, "入渠終了2回目はない");\r
291                         break;\r
292                     case 10000:\r
293                         PAssert.That(() => ensei.Equals(result), "遠征終了2回目");\r
294                         return;\r
295                     default:\r
296                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
297                         break;\r
298                 }\r
299                 result = null;\r
300                 timer.ElapseTime(1000);\r
301             }\r
302         }\r
303 \r
304         /// <summary>\r
305         /// リピートを中断・再開する\r
306         /// </summary>\r
307         [TestMethod]\r
308         public void SuspendRepeat()\r
309         {\r
310             var timer = new MockTimer();\r
311             Message result = null;\r
312             var manager =\r
313                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
314             var expected = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
315             while (true)\r
316             {\r
317                 switch (timer.Elapsed)\r
318                 {\r
319                     case 0:\r
320                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
321                         PAssert.That(() => expected.Equals(result));\r
322                         break;\r
323                     case 1000:\r
324                         manager.SuspendRepeat();\r
325                         break;\r
326                     case 11000:\r
327                         manager.ResumeRepeat();\r
328                         break;\r
329                     case 12000:\r
330                         PAssert.That(() => expected.Equals(result));\r
331                         return;\r
332                     default:\r
333                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
334                         break;\r
335                 }\r
336                 result = null;\r
337                 timer.ElapseTime(1000);\r
338             }\r
339         }\r
340 \r
341         /// <summary>\r
342         /// リピート中の特定の通知を止める\r
343         /// </summary>\r
344         [TestMethod]\r
345         public void StopSpecificRepeatingNotification()\r
346         {\r
347             var timer = new MockTimer();\r
348             Message result = null;\r
349             var manager =\r
350                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
351             var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
352             var expected2 = new Message {Title = "遠征が終わりました", Body = "第三艦隊 海上護衛任務", Name = "遠征終了"};\r
353             while (true)\r
354             {\r
355                 switch (timer.Elapsed)\r
356                 {\r
357                     case 0:\r
358                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
359                         manager.Enqueue("遠征終了", 2, "海上護衛任務", 10);\r
360                         PAssert.That(() => expected1.Equals(result));\r
361                         break;\r
362                     case 2000:\r
363                         PAssert.That(() => expected2.Equals(result));\r
364                         break;\r
365                     case 5000:\r
366                         manager.StopRepeat("遠征終了", 1);\r
367                         break;\r
368                     case 12000:\r
369                         PAssert.That(() => expected2.Equals(result));\r
370                         return;\r
371                     default:\r
372                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
373                         break;\r
374 \r
375                 }\r
376                 result = null;\r
377                 timer.ElapseTime(1000);\r
378             }\r
379         }\r
380 \r
381         /// <summary>\r
382         /// 継続中のリピートは艦隊やドックの番号だけ通知する\r
383         /// </summary>\r
384         [TestMethod]\r
385         public void ContinueRepeatWithoutSubject()\r
386         {\r
387             var timer = new MockTimer();\r
388             Message result = null;\r
389             var manager =\r
390                 new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, timer);\r
391             var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"};\r
392             var expected2 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 ", Name = "遠征終了"};\r
393             while (true)\r
394             {\r
395                 switch (timer.Elapsed)\r
396                 {\r
397                     case 0:\r
398                         manager.Enqueue("遠征終了", 1, "防空射撃演習", 10);\r
399                         PAssert.That(() => expected1.Equals(result));\r
400                         break;\r
401                     case 2000:\r
402                         manager.StopRepeat("遠征終了", true);\r
403                         break;\r
404                     case 10000:\r
405                         PAssert.That(() => expected2.Equals(result));\r
406                         break;\r
407                     case 11000:\r
408                         manager.StopRepeat("遠征終了", 1);\r
409                         break;\r
410                     case 21000:\r
411                         return;\r
412                     default:\r
413                         PAssert.That(() => result == null, timer.Elapsed.ToString());\r
414                         break;\r
415 \r
416                 }\r
417                 result = null;\r
418                 timer.ElapseTime(1000);\r
419             }\r
420         }\r
421     }\r
422 }