// Copyright (C) 2017 Kazuhiro Fujieda // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using ExpressionToCodeLib; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace KancolleSniffer.Test { [TestClass] public class NotificationManagerTest { private class TimeProvider { private DateTime _now = new DateTime(2017, 11, 1); public DateTime GetNow() { var now = _now; _now += TimeSpan.FromSeconds(1); return now; } } private class Message { public string Title { private get; set; } public string Body { private get; set; } public string Name { private get; set; } public bool Equals(Message other) => other != null && Title == other.Title && Body == other.Body && Name == other.Name; public Message Repeat => new Message {Title = "[リピート] " + Title, Body = Body, Name = Name}; public Message Cont => new Message {Title = "[継続] " + Title, Body = Body, Name = Name}; } /// /// 単発 /// [TestMethod] public void SingleNotification() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); manager.Enqueue("遠征終了", 1, "防空射撃演習"); manager.Flash(); PAssert.That(() => new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}.Equals(result)); } /// /// 連続した通知の間隔を二秒空ける /// [TestMethod] public void TwoNotificationAtSameTime() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); manager.Enqueue("遠征終了", 1, "防空射撃演習"); manager.Enqueue("疲労回復49", 1, "cond49"); manager.Flash(); PAssert.That(() => new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}.Equals(result)); result = null; manager.Flash(); PAssert.That(() => result == null); manager.Flash(); PAssert.That(() => new Message {Title = "疲労が回復しました", Body = "第二艦隊", Name = "疲労回復"}.Equals(result)); } /// /// 一つ目の通知の一秒後に投入された通知は一秒ずらす /// [TestMethod] public void TwoNotification1SecDelay() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); manager.Enqueue("建造完了", 0, ""); manager.Flash(); PAssert.That(() => new Message {Title = "建造が終わりました", Body = "第一ドック", Name = "建造完了"}.Equals(result)); manager.Flash(); manager.Enqueue("建造完了", 1, ""); manager.Flash(); PAssert.That(() => new Message {Title = "建造が終わりました", Body = "第二ドック", Name = "建造完了"}.Equals(result)); } /// /// 通知をリピートさせる /// [TestMethod] public void SingleRepeatableNotification() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); var expected = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}; var elapsed = 0; while (true) { switch (elapsed) { case 0: manager.Enqueue("遠征終了", 1, "防空射撃演習", 2); manager.Flash(); PAssert.That(() => expected.Equals(result)); break; case 2000: manager.Flash(); PAssert.That(() => expected.Repeat.Equals(result)); break; case 4000: manager.Flash(); PAssert.That(() => expected.Repeat.Equals(result)); return; default: manager.Flash(); PAssert.That(() => result == null, elapsed.ToString()); break; } result = null; elapsed += 1000; } } /// /// 二つの通知をリピートさせる /// [TestMethod] public void TwoRepeatableNotification() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}; var hakuchi = new Message {Title = "泊地修理 第一艦隊", Body = "20分経過しました。", Name = "泊地修理20分経過"}; var elapsed = 0; while (true) { switch (elapsed) { case 0: manager.Enqueue("遠征終了", 1, "防空射撃演習", 10); manager.Flash(); PAssert.That(() => ensei.Equals(result)); break; case 2000: manager.Enqueue("泊地修理20分経過", 0, "", 5); manager.Flash(); PAssert.That(() => hakuchi.Equals(result)); break; case 7000: manager.Flash(); PAssert.That(() => hakuchi.Repeat.Equals(result), "泊地修理2回目"); break; case 10000: manager.Flash(); PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目"); return; default: manager.Flash(); PAssert.That(() => result == null, elapsed.ToString()); break; } result = null; elapsed += 1000; } } /// /// スケジュールがぶつかる二つの通知をリピートさせる /// [TestMethod] public void TwoRepeatableNotification1SecDelay() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}; var hakuchi = new Message {Title = "泊地修理 第一艦隊", Body = "20分経過しました。", Name = "泊地修理20分経過"}; var elapsed = 0; while (true) { switch (elapsed) { case 0: manager.Enqueue("遠征終了", 1, "防空射撃演習", 3); manager.Flash(); PAssert.That(() => ensei.Equals(result)); break; case 1000: manager.Enqueue("泊地修理20分経過", 0, "", 2); manager.Flash(); break; case 2000: manager.Flash(); PAssert.That(() => hakuchi.Equals(result)); break; case 4000: manager.Flash(); PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目"); break; case 6000: manager.Flash(); PAssert.That(() => hakuchi.Repeat.Equals(result), "泊地修理2回目"); return; default: manager.Flash(); PAssert.That(() => result == null, elapsed.ToString()); break; } result = null; elapsed += 1000; } } /// /// リピートしている通知を止める /// [TestMethod] public void RemoveRepeatableNotification() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}; var nyukyo = new Message {Title = "入渠が終わりました", Body = "第一ドック 綾波改二", Name = "入渠終了"}; var elapsed = 0; while (true) { switch (elapsed) { case 0: manager.Enqueue("遠征終了", 1, "防空射撃演習", 10); manager.Flash(); PAssert.That(() => ensei.Equals(result)); break; case 2000: manager.Enqueue("入渠終了", 0, "綾波改二", 5); manager.Flash(); PAssert.That(() => nyukyo.Equals(result)); break; case 3000: manager.StopRepeat("入渠終了"); manager.Flash(); break; case 7000: manager.Flash(); PAssert.That(() => result == null, "入渠終了2回目はない"); break; case 10000: manager.Flash(); PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目"); return; default: manager.Flash(); PAssert.That(() => result == null, elapsed.ToString()); break; } result = null; elapsed += 1000; } } /// /// リピートを中断・再開する /// [TestMethod] public void SuspendRepeat() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); var expected = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}; var elapsed = 0; while (true) { switch (elapsed) { case 0: manager.Enqueue("遠征終了", 1, "防空射撃演習", 10); manager.Flash(); PAssert.That(() => expected.Equals(result)); break; case 1000: manager.Flash(); manager.SuspendRepeat(); break; case 11000: manager.Flash(); manager.ResumeRepeat(); break; case 12000: manager.Flash(); PAssert.That(() => expected.Repeat.Equals(result)); return; default: manager.Flash(); PAssert.That(() => result == null, elapsed.ToString()); break; } result = null; elapsed += 1000; } } /// /// リピートを例外付きで中断・再開する /// [TestMethod] public void SuspendRepeatWithException() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); var ensei = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}; var taiha = new Message {Title = "大破した艦娘がいます", Body = "摩耶改二", Name = "大破警告"}; var elapsed = 0; while (true) { switch (elapsed) { case 0: manager.Enqueue("遠征終了", 1, "防空射撃演習", 10); manager.Flash(); PAssert.That(() => ensei.Equals(result)); break; case 1000: manager.Flash(); manager.SuspendRepeat("大破警告"); break; case 2000: manager.Enqueue("大破警告", "摩耶改二", 8); manager.Flash(); PAssert.That(() => taiha.Equals(result)); break; case 10000: manager.Flash(); PAssert.That(() => taiha.Repeat.Equals(result)); break; case 11000: manager.Flash(); manager.ResumeRepeat(); break; case 12000: manager.Flash(); PAssert.That(() => ensei.Repeat.Equals(result)); return; default: manager.Flash(); PAssert.That(() => result == null, elapsed.ToString()); break; } result = null; elapsed += 1000; } } /// /// リピート中の特定の通知を止める /// [TestMethod] public void StopSpecificRepeatingNotification() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}; var expected2 = new Message {Title = "遠征が終わりました", Body = "第三艦隊 海上護衛任務", Name = "遠征終了"}; var elapsed = 0; while (true) { switch (elapsed) { case 0: manager.Enqueue("遠征終了", 1, "防空射撃演習", 10); manager.Flash(); PAssert.That(() => expected1.Equals(result)); break; case 1000: manager.Enqueue("遠征終了", 2, "海上護衛任務", 10); manager.Flash(); break; case 2000: manager.Flash(); PAssert.That(() => expected2.Equals(result)); break; case 5000: manager.Flash(); manager.StopRepeat("遠征終了", 1); break; case 12000: manager.Flash(); PAssert.That(() => expected2.Repeat.Equals(result)); return; default: manager.Flash(); PAssert.That(() => result == null, elapsed.ToString()); break; } result = null; elapsed += 1000; } } /// /// 継続中のリピートは艦隊やドックの番号だけ通知する /// [TestMethod] public void ContinueRepeatWithoutSubject() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}; var expected2 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 ", Name = "遠征終了"}; var elapsed = 0; while (true) { switch (elapsed) { case 0: manager.Enqueue("遠征終了", 1, "防空射撃演習", 10); manager.Flash(); PAssert.That(() => expected1.Equals(result)); break; case 2000: manager.Flash(); manager.StopRepeat("遠征終了", true); break; case 10000: manager.Flash(); PAssert.That(() => expected2.Cont.Equals(result)); break; case 11000: manager.Flash(); manager.StopRepeat("遠征終了", 1); break; case 21000: manager.Flash(); return; default: manager.Flash(); PAssert.That(() => result == null, elapsed.ToString()); break; } result = null; elapsed += 1000; } } /// /// 予告する /// [TestMethod] public void PreliminaryNotification() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); var expected = new Message {Title = "[予告] 遠征が終わりました", Body = "第二艦隊 防空射撃演習", Name = "遠征終了"}; manager.Enqueue("遠征終了", 1, "防空射撃演習", 0, true); manager.Flash(); PAssert.That(() => expected.Equals(result)); } /// /// 同時に通知されるタイトルが同じ通知をマージする /// [TestMethod] public void MergeTwoNotificationsWithSameTitle() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); manager.Enqueue("遠征終了", 1, "防空射撃演習", 10); manager.Enqueue("遠征終了", 2, "海上護衛任務", 10); manager.Flash(); PAssert.That(() => new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習\r\n第三艦隊 海上護衛任務", Name = "遠征終了"}.Equals(result)); } /// /// マージされた二つの通知の一方を止める /// [TestMethod] public void StopOneOfMergedNotifications() { var time = new TimeProvider(); Message result = null; var manager = new NotificationManager((t, b, n) => { result = new Message {Title = t, Body = b, Name = n}; }, time.GetNow); var expected1 = new Message {Title = "遠征が終わりました", Body = "第二艦隊 防空射撃演習\r\n第三艦隊 海上護衛任務", Name = "遠征終了"}; var expected2 = new Message {Title = "遠征が終わりました", Body = "第三艦隊 海上護衛任務", Name = "遠征終了"}; var elapsed = 0; while (true) { switch (elapsed) { case 0: manager.Enqueue("遠征終了", 1, "防空射撃演習", 10); manager.Enqueue("遠征終了", 2, "海上護衛任務", 10); manager.Flash(); PAssert.That(() => expected1.Equals(result)); break; case 5000: manager.Flash(); manager.StopRepeat("遠征終了", 1); break; case 10000: manager.Flash(); PAssert.That(() => expected2.Repeat.Equals(result)); return; default: manager.Flash(); PAssert.That(() => result == null, elapsed.ToString()); break; } result = null; elapsed += 1000; } } } }