[TestClass]\r
public class NotificationManagerTest\r
{\r
- private class MockTimer : NotificationManager.ITimer\r
+ private class TimeProvider\r
{\r
- private int _elapsed;\r
- private bool _enabled;\r
+ private DateTime _now = new DateTime(2017, 11, 1);\r
\r
- public int Interval { get; set; }\r
-\r
- public bool Enabled\r
- {\r
- get => _enabled;\r
- set\r
- {\r
- _enabled = value;\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
+ public DateTime GetNow()\r
{\r
- Enabled = false;\r
- }\r
-\r
- public void ElapseTime(int millis)\r
- {\r
- if (!Enabled)\r
- return;\r
- var after = _elapsed + millis;\r
- for (var n = _elapsed / Interval; n < after / Interval; n++)\r
- {\r
- Tick?.Invoke(this, EventArgs.Empty);\r
- }\r
- _elapsed = after;\r
+ var now = _now;\r
+ _now += TimeSpan.FromSeconds(1);\r
+ return now;\r
}\r
}\r
\r
\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
[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
[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
[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
- manager.Enqueue("建造完了", "第一ドック");\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.Enqueue("建造完了", "第二ドック");\r
- timer.ElapseTime(1000);\r
+ manager.Flash();\r
+ manager.Enqueue("建造完了", 1, "");\r
+ manager.Flash();\r
PAssert.That(() => new Message {Title = "建造が終わりました", Body = "第二ドック", Name = "建造完了"}.Equals(result));\r
}\r
+\r
+ /// <summary>\r
+ /// 通知をリピートさせる\r
+ /// </summary>\r
+ [TestMethod]\r
+ public void SingleRepeatableNotification()\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
+ var elapsed = 0;\r
+ while (true)\r
+ {\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
+ manager.Flash();\r
+ PAssert.That(() => expected.Repeat.Equals(result));\r
+ break;\r
+ case 4000:\r
+ manager.Flash();\r
+ PAssert.That(() => expected.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 TwoRepeatableNotification()\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 hakuchi = new Message {Title = "泊地修理 第一艦隊", Body = "20分経過しました。", Name = "泊地修理20分経過"};\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 2000:\r
+ manager.Enqueue("泊地修理20分経過", 0, "", 5);\r
+ manager.Flash();\r
+ PAssert.That(() => hakuchi.Equals(result));\r
+ break;\r
+ case 7000:\r
+ manager.Flash();\r
+ PAssert.That(() => hakuchi.Repeat.Equals(result), "泊地修理2回目");\r
+ break;\r
+ case 10000:\r
+ manager.Flash();\r
+ PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\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 TwoRepeatableNotification1SecDelay()\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 hakuchi = new Message {Title = "泊地修理 第一艦隊", Body = "20分経過しました。", Name = "泊地修理20分経過"};\r
+ var elapsed = 0;\r
+ while (true)\r
+ {\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
+ manager.Flash();\r
+ PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\r
+ break;\r
+ case 6000:\r
+ manager.Flash();\r
+ PAssert.That(() => hakuchi.Repeat.Equals(result), "泊地修理2回目");\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 RemoveRepeatableNotification()\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 nyukyo = 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 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
+ manager.Flash();\r
+ PAssert.That(() => ensei.Repeat.Equals(result), "遠征終了2回目");\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 SuspendRepeat()\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
+ 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(() => 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
+ manager.Flash();\r
+ PAssert.That(() => expected.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 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
+ /// <summary>\r
+ /// リピート中の特定の通知を止める\r
+ /// </summary>\r
+ [TestMethod]\r
+ public void StopSpecificRepeatingNotification()\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 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
+ 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
+ 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
+ elapsed += 1000;\r
+ }\r
+ }\r
}\r
}
\ No newline at end of file