// zlib/libpng License
//
// Copyright (c) 2018 Sinoa
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
using System;
using System.Collections;
using System.Collections.Generic;
using IceMilkTea.Core;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
namespace IceMilkTeaTestDynamic.Core
{
#region テスト確認用クラス
/*
* テストで用いるクラスは以下の継承構造になります。
*
* GameService(IceMilkTeaにおけるサービスの抽象クラス)
* ├ ServiceBaseA(ユーザー定義クラスの最基底サービスクラスでありキーとなるクラス)
* │ └ServiceA_1_0
* │ ├ ServiceA_2_0
* │ └ ServiceA_2_1
* │
* └ ServiceBaseB(ユーザー定義クラスの最基底サービスクラスでありキーとなるクラス)
* └ ServiceB_1_0
* ├ ServiceB_2_0
* └ ServiceB_2_1
*
* IceMilkTeaでは "GameServiceクラスを直接継承したクラス" がキーとなるクラスとなり
* そのクラスを継承したすべての派生クラスは、キーとなるクラスが重複して登録されない制約が付きます。
*/
///
/// サービスAの基本テストクラスです
///
public class ServiceBaseA : GameService
{
///
/// サービスが起動済みかどうか
///
public bool Startuped { get; set; }
///
/// サービスが停止済みかどうか
///
public bool Stopped { get; set; }
///
/// PreUpdate毎にカウントし続けるカウンタ
///
public int StepCount { get; set; }
///
/// サービスの起動処理を行います
///
/// サービスの起動情報を設定します
protected internal override void Startup(out GameServiceStartupInfo info)
{
// サービス起動情報の初期化
info = new GameServiceStartupInfo()
{
// 更新関数テーブルの初期化
UpdateFunctionTable = new Dictionary()
{
{GameServiceUpdateTiming.PreUpdate, PreUpdate}
}
};
// サービスは起動済みである
Startuped = true;
}
///
/// サービスの停止処理を行います
///
protected internal override void Shutdown()
{
// サービスは停止済みである
Stopped = true;
}
///
/// Update前の処理を実行します
///
private void PreUpdate()
{
// カウントし続ける
StepCount += 1;
}
}
///
/// サービスAの基本クラスから派生したサービスA1クラスです
///
public class ServiceA_1_0 : ServiceBaseA
{
}
///
/// サービスAクラスから更に派生したサービスA2クラスです
///
public class ServiceA_2_0 : ServiceA_1_0
{
}
///
/// サービスAクラスからもう一つ派生したサービスA2の二つ目のクラスです
///
public class ServiceA_2_1 : ServiceA_1_0
{
}
///
/// サービスBの基本テストクラスです
///
public class ServiceBaseB : GameService
{
}
///
/// サービスBの基本クラスから派生したサービスB1クラスです
///
public class ServiceB_1_0 : ServiceBaseB
{
}
///
/// サービスBクラスから更に派生したサービスB2クラスです
///
public class ServiceB_2_0 : ServiceB_1_0
{
}
///
/// サービスBクラスからもう一つ派生したサービスB2の二つ目のクラスです
///
public class ServiceB_2_1 : ServiceB_1_0
{
}
///
/// ServiceBaseAサービスを削除するサービスです
///
public class ServiceBaseARemoveService : GameService
{
///
/// サービスの起動処理を実行します
///
/// サービスの起動情報を設定します
protected internal override void Startup(out GameServiceStartupInfo info)
{
// サービス起動情報の初期化
info = new GameServiceStartupInfo()
{
// 更新関数テーブルの初期化
UpdateFunctionTable = new Dictionary()
{
{GameServiceUpdateTiming.PreUpdate, PreUpdate}
}
};
}
///
/// Update前の処理を行います
///
private void PreUpdate()
{
// マネージャを取得
var manager = GameMain.Current.ServiceManager;
// サービスが有るなら
if (manager.Exists())
{
// アクティブを戻して削除する
manager.SetActiveService(true);
manager.RemoveService();
}
}
}
#endregion
///
/// IceMilkTeaの GameServiceManager をテストするクラスです
///
public class ServiceManagerTest
{
// メンバ変数定義
private GameServiceManager manager;
///
/// テストの開始準備を行います
///
[OneTimeSetUp]
public void Setup()
{
// マネージャの起動では例外さえ出なければ良いとする
Assert.DoesNotThrow(() =>
{
// 空ゲームメインで動作を上書きしてサービスマネージャを取得する
GameMain.OverrideGameMain(ScriptableObject.CreateInstance());
manager = GameMain.Current.ServiceManager;
});
}
///
/// テストの終了処理を行います
///
[OneTimeTearDown]
public void Celanup()
{
// ここでは何もしない
}
#region Add系テスト
///
/// サービスの追加をテストします。
/// ついでに削除系のテストも行います。
///
/// Unityのフレーム待機をするための列挙子を返します
[UnityTest, Order(10)]
public IEnumerator AddServiceTest()
{
// サービス追加に成功する関数
var addSuccess = new Action(() =>
{
// そもそもnull渡しは死ぬ
Assert.Throws(() => manager.AddService(null));
// サービスA2_0、サービスB1_0を登録できる事を確認する
Assert.DoesNotThrow(() => manager.AddService(new ServiceA_2_0()));
Assert.DoesNotThrow(() => manager.AddService(new ServiceB_1_0()));
});
// サービスの追加に失敗する関数
var addFailed = new Action(() =>
{
// サービスA、サービスBのあらゆるサービスが登録出来ないことを確認する(ついでに重複登録出来ないことも確認する)
Assert.Throws(() => manager.AddService(new ServiceBaseA()));
Assert.Throws(() => manager.AddService(new ServiceA_1_0()));
Assert.Throws(() => manager.AddService(new ServiceA_2_0())); // 重複確認
Assert.Throws(() => manager.AddService(new ServiceA_2_1()));
Assert.Throws(() => manager.AddService(new ServiceBaseB()));
Assert.Throws(() => manager.AddService(new ServiceB_1_0())); // 重複確認
Assert.Throws(() => manager.AddService(new ServiceB_2_0()));
Assert.Throws(() => manager.AddService(new ServiceB_2_1()));
});
// サービスのシャットダウン中のため追加に失敗する関数
var addInvalidOperation = new Action(() =>
{
// サービスの削除中の場合Get可能なサービスはInvalidOperationが発生し、関係ないサービスは引き続き追加済み例外が発生することを確認する
Assert.Throws(() => manager.AddService(new ServiceBaseA()));
Assert.Throws(() => manager.AddService(new ServiceA_1_0()));
Assert.Throws(() => manager.AddService(new ServiceA_2_0())); // 重複確認
Assert.Throws(() => manager.AddService(new ServiceA_2_1()));
Assert.Throws(() => manager.AddService(new ServiceBaseB()));
Assert.Throws(() => manager.AddService(new ServiceB_1_0())); // 重複確認
Assert.Throws(() => manager.AddService(new ServiceB_2_0()));
Assert.Throws(() => manager.AddService(new ServiceB_2_1()));
});
// 共通の追加テスト関数を呼ぶ
return AddTestCommon(addSuccess, addFailed, addInvalidOperation);
}
///
/// サービスの追加(TryAddService)をテストします
/// ついでに削除系のテストも行います。
///
/// Unityのフレーム待機をするための列挙子を返します
[UnityTest, Order(20)]
public IEnumerator TryAddServiceTest()
{
// サービス追加に成功する関数
var addSuccess = new Action(() =>
{
// そもそもnull渡しは死ぬ
Assert.Throws(() => manager.TryAddService(null));
// サービスA2_0、サービスB1_0を登録できる事を確認する
Assert.IsTrue(manager.TryAddService(new ServiceA_2_0()));
Assert.IsTrue(manager.TryAddService(new ServiceB_1_0()));
});
// サービスの追加に失敗する関数
var addFailed = new Action(() =>
{
// サービスA、サービスBのあらゆるサービスが登録出来ないことを確認する(ついでに重複登録出来ないことも確認する)
Assert.IsFalse(manager.TryAddService(new ServiceBaseA()));
Assert.IsFalse(manager.TryAddService(new ServiceA_1_0()));
Assert.IsFalse(manager.TryAddService(new ServiceA_2_1()));
Assert.IsFalse(manager.TryAddService(new ServiceA_2_0())); // 重複確認
Assert.IsFalse(manager.TryAddService(new ServiceBaseB()));
Assert.IsFalse(manager.TryAddService(new ServiceB_2_0()));
Assert.IsFalse(manager.TryAddService(new ServiceB_2_1()));
Assert.IsFalse(manager.TryAddService(new ServiceB_1_0())); // 重複確認
});
// 共通の追加テスト関数を呼ぶ(TryAddは例外を気にしない関数のため、この関数は通常のAddFailedの処理とみなす)
return AddTestCommon(addSuccess, addFailed, addFailed);
}
///
/// AddService系の共通テスト関数です。
///
/// AddServiceが成功する関数
/// AddService全般失敗する関数
/// 削除中のためGet可能なサービスがInvalidOperationする関数
/// Unityのフレーム待機をするための列挙子を返します
private IEnumerator AddTestCommon(Action addSuccess, Action addFailed, Action addInvalidOperation)
{
// サービスの追加をして、直後に追加に失敗するかを確認する
addSuccess();
addFailed();
yield return null;
// サービス削除直後は、まだサービスが存在していることを保証しなければならないため
// 追加関数を叩くと失敗することになるので、その確認をする
manager.RemoveService();
manager.RemoveService();
addInvalidOperation();
yield return null;
// 次のフレームには削除は完了しているので、正常に追加が出来ることを確認する
addSuccess();
addFailed();
// 削除して次のフレームへすすめる
manager.RemoveService();
manager.RemoveService();
yield return null;
}
#endregion
#region Get系テスト
///
/// サービスの取得をテストします。
/// ついでに削除系のテストも行います。
///
/// Unityのフレーム待機をするための列挙子を返します
[UnityTest, Order(30)]
public IEnumerator GetServiceTest()
{
// サービスAクラスは末端の2系サービスを追加し、GameServiceとサービスA2_1以外でサービスの取得が出来ることを確認
// サービスBクラスは中間の1系サービスを追加し、GameServiceとサービスB2系以外でサービスの取得が出来ることを確認
// 全サービス取得が出来ないときの関数
var allServiceNotFoundTest = new Action(() =>
{
// すべての関数にて例外が発生すれば全サービス取得出来ないということになる
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
});
// サービスの部分取得に成功する場合の関数
var getServiceTest = new Action(() =>
{
// 取得出来ないサービスは例外が発生し、取得できるサービスは例外が発生せず値が取れることでテストが通ることになる
Assert.Throws(() => manager.GetService()); // 最基底クラスでは取得は出来ない
Assert.DoesNotThrow(() => manager.GetService()); // A2_0の継承元
Assert.IsNotNull(manager.GetService()); // A2_0の継承元
Assert.DoesNotThrow(() => manager.GetService()); // A2_0の継承元
Assert.IsNotNull(manager.GetService()); // A2_0の継承元
Assert.DoesNotThrow(() => manager.GetService()); // A2_0ご本人様
Assert.IsNotNull(manager.GetService()); // A2_0ご本人様
Assert.Throws(() => manager.GetService()); // A2_0とは関係のないサービス
Assert.DoesNotThrow(() => manager.GetService()); // B1_0の継承元
Assert.IsNotNull(manager.GetService()); // B1_0の継承元
Assert.DoesNotThrow(() => manager.GetService()); // B1_0ご本人様
Assert.IsNotNull(manager.GetService()); // B1_0ご本人様
Assert.Throws(() => manager.GetService()); // B1_0を継承しているがB1_0から見たら関係ないサービス
Assert.Throws(() => manager.GetService()); // B1_0を継承しているがB1_0から見たら関係ないサービス
});
// Get系共通テストの関数を呼ぶ
return GetTestCommon(allServiceNotFoundTest, getServiceTest);
}
///
/// サービスの取得(TryGetService)をテストします。
/// ついでに削除系のテストも行います。
///
/// Unityのフレーム待機をするための列挙子を返します
[UnityTest, Order(40)]
public IEnumerator TryGetServiceTest()
{
// TryGetServiceの基本の振る舞いはGetServiceと同じで
// リザルトが例外ではなく戻り値及び設定される値の確認となる
// 格納用変数宣言
var gameService = default(GameService);
var serviceBaseA = default(ServiceBaseA);
var serviceA_1_0 = default(ServiceA_1_0);
var serviceA_2_0 = default(ServiceA_2_0);
var serviceA_2_1 = default(ServiceA_2_1);
var serviceBaseB = default(ServiceBaseB);
var serviceB_1_0 = default(ServiceB_1_0);
var serviceB_2_0 = default(ServiceB_2_0);
var serviceB_2_1 = default(ServiceB_2_1);
// 全サービス取得が出来ないときの関数
var allServiceNotFoundTest = new Action(() =>
{
// すべて false が返されて、値が null に設定されればサービスは全部取得出来ないということになる
Assert.IsFalse(manager.TryGetService(out gameService)); Assert.IsNull(gameService);
Assert.IsFalse(manager.TryGetService(out serviceBaseA)); Assert.IsNull(serviceBaseA);
Assert.IsFalse(manager.TryGetService(out serviceA_1_0)); Assert.IsNull(serviceA_1_0);
Assert.IsFalse(manager.TryGetService(out serviceA_2_0)); Assert.IsNull(serviceA_2_0);
Assert.IsFalse(manager.TryGetService(out serviceA_2_1)); Assert.IsNull(serviceA_2_1);
Assert.IsFalse(manager.TryGetService(out serviceBaseB)); Assert.IsNull(serviceBaseB);
Assert.IsFalse(manager.TryGetService(out serviceB_1_0)); Assert.IsNull(serviceB_1_0);
Assert.IsFalse(manager.TryGetService(out serviceB_2_0)); Assert.IsNull(serviceB_2_0);
Assert.IsFalse(manager.TryGetService(out serviceB_2_1)); Assert.IsNull(serviceB_2_1);
});
// サービスの部分取得に成功する場合の関数
var getServiceTest = new Action(() =>
{
// 取得できる場合は true が設定されて、値がセットされていればOK
Assert.IsFalse(manager.TryGetService(out gameService)); Assert.IsNull(gameService); // 最基底クラスでは取得は出来ない
Assert.IsTrue(manager.TryGetService(out serviceBaseA)); Assert.IsNotNull(serviceBaseA); // A2_0の継承元
Assert.IsTrue(manager.TryGetService(out serviceA_1_0)); Assert.IsNotNull(serviceA_1_0); // A2_0の継承元
Assert.IsTrue(manager.TryGetService(out serviceA_2_0)); Assert.IsNotNull(serviceA_2_0); // A2_0ご本人様
Assert.IsFalse(manager.TryGetService(out serviceA_2_1)); Assert.IsNull(serviceA_2_1); // A2_0とは関係のないサービス
Assert.IsTrue(manager.TryGetService(out serviceBaseB)); Assert.IsNotNull(serviceBaseB); // B1_0の継承元
Assert.IsTrue(manager.TryGetService(out serviceB_1_0)); Assert.IsNotNull(serviceB_1_0); // B1_0ご本人様
Assert.IsFalse(manager.TryGetService(out serviceB_2_0)); Assert.IsNull(serviceB_2_0); // B1_0を継承しているがB1_0から見たら関係ないサービス
Assert.IsFalse(manager.TryGetService(out serviceB_2_1)); Assert.IsNull(serviceB_2_1); // B1_0を継承しているがB1_0から見たら関係ないサービス
});
// Get系共通テストの関数を呼ぶ
return GetTestCommon(allServiceNotFoundTest, getServiceTest);
}
///
/// GetService系の共通テスト関数です。
///
/// すべてのサービスの取得が出来ないときの関数
/// 部分的に取得に成功する関数
/// Unityのフレーム待機をするための列挙子を返します
private IEnumerator GetTestCommon(Action allServiceNotFoundTest, Action getServiceTest)
{
// この時点ではまだ全サービスの取得が出来ないことを確認する
allServiceNotFoundTest();
// 通常は追加された直後のサービスは起動していないが、取得は可能であることは保証しているべきなので
// サービスA2_0、サービスB1_0の取得系がちゃんと動作するか確認して、次のフレームでも同じ動作をしていることを期待する
manager.AddService(new ServiceA_2_0());
manager.AddService(new ServiceB_1_0());
getServiceTest();
yield return null;
getServiceTest();
// サービスのアクティブを切ってもサービスの取得ができることを確認する
manager.SetActiveService(false);
manager.SetActiveService(false);
getServiceTest();
// 通常は削除された直後のサービスはまだ停止していないので、まだ取得できる状態を保証しているべきで
// まだサービスが取得出来ることを確認して、次のフレームで取得ができなくなっていることを確認する
manager.RemoveService();
manager.RemoveService();
getServiceTest();
yield return null;
allServiceNotFoundTest();
}
#endregion
#region Remove系テスト
///
/// サービスの削除テストをします
///
/// Unityのフレーム待機をするための列挙子を返します
[UnityTest, Order(80)]
public IEnumerator RevemoServiceTest()
{
// 削除する時に指定が可能なサービス型は、キーとなる既定クラスが一致して
// 実際に登録されているサービスの型がキャスト可能な型(ただしGameServiceは除く)になる事を確認する
// 全サービス取得が出来ないときの関数
var allServiceNotFoundTest = new Action(() =>
{
// すべての関数にて例外が発生すれば全サービス取得出来ないということになる
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
Assert.Throws(() => manager.GetService());
});
// サービスの部分取得に成功する場合の関数
var getServiceTest = new Action(() =>
{
// 取得出来ないサービスは例外が発生し、取得できるサービスは例外が発生せず値が取れることでテストが通ることになる
Assert.Throws(() => manager.GetService()); // 最基底クラスでは取得は出来ない
Assert.DoesNotThrow(() => manager.GetService()); // A2_0の継承元
Assert.IsNotNull(manager.GetService()); // A2_0の継承元
Assert.DoesNotThrow(() => manager.GetService()); // A2_0の継承元
Assert.IsNotNull(manager.GetService()); // A2_0の継承元
Assert.DoesNotThrow(() => manager.GetService()); // A2_0ご本人様
Assert.IsNotNull(manager.GetService()); // A2_0ご本人様
Assert.Throws(() => manager.GetService()); // A2_0とは関係のないサービス
Assert.DoesNotThrow(() => manager.GetService()); // B1_0の継承元
Assert.IsNotNull(manager.GetService()); // B1_0の継承元
Assert.DoesNotThrow(() => manager.GetService()); // B1_0ご本人様
Assert.IsNotNull(manager.GetService()); // B1_0ご本人様
Assert.Throws(() => manager.GetService()); // B1_0を継承しているがB1_0から見たら関係ないサービス
Assert.Throws(() => manager.GetService()); // B1_0を継承しているがB1_0から見たら関係ないサービス
});
// 現時点ではすべてのサービスは取得出来ないはず
allServiceNotFoundTest();
// サービスを追加して存在が確認出来ることを確認
manager.AddService(new ServiceA_2_0());
manager.AddService(new ServiceB_1_0());
getServiceTest();
// まずは直接同じ型を指定して削除が通るか確認
manager.RemoveService();
manager.RemoveService();
yield return null;
allServiceNotFoundTest();
// 一つ前の継承クラスの型からでも削除が通るか確認
manager.AddService(new ServiceA_2_0());
manager.AddService(new ServiceB_1_0());
getServiceTest();
manager.RemoveService();
manager.RemoveService();
yield return null;
allServiceNotFoundTest();
// どちらのサービスも最基底クラスを指定したら削除が通るか確認
manager.AddService(new ServiceA_2_0());
manager.AddService(new ServiceB_1_0());
getServiceTest();
manager.RemoveService();
manager.RemoveService();
yield return null;
allServiceNotFoundTest();
// GameServiceを指定しても何も消えないことを確認
manager.AddService(new ServiceA_2_0());
manager.AddService(new ServiceB_1_0());
getServiceTest();
manager.RemoveService();
yield return null;
getServiceTest();
// 関係ないサービスを指定しても消えないことを確認
manager.RemoveService();
manager.RemoveService();
yield return null;
getServiceTest();
// サービスを消してフレームを進める
manager.RemoveService();
manager.RemoveService();
yield return null;
}
#endregion
#region サービスのコントロール系テスト
///
/// サービスのアクティブ設定をのテストをします
///
/// Unityのフレーム待機をするための列挙子を返します
[UnityTest, Order(50)]
public IEnumerator ActiveDeactiveTest()
{
// Active操作はフレーム進行関係なくアクティブ状態は直ちに反映されるかを確認する
// 確認用サービスを生成して登録
var service = new ServiceBaseA();
manager.AddService(service);
// この時点ではカウンタは0であることと、まだ起動していないこと、アクティブ状態であることを確認してフレームを進める
Assert.AreEqual(0, service.StepCount);
Assert.IsFalse(service.Startuped);
Assert.IsTrue(manager.IsActiveService());
yield return null;
// フレームが進んだのでカウンタが進んだことを確認して、もう起動済みで、アクティブの切り替わりの確認をして、フレームを進める
Assert.AreEqual(1, service.StepCount);
Assert.IsTrue(service.Startuped);
Assert.IsTrue(manager.IsActiveService());
manager.SetActiveService(false);
Assert.IsFalse(manager.IsActiveService());
yield return null;
// 非アクティブ状態なのでカウンタが進んでいないことを確認して、アクティブ状態にして、アクティブ変化を確認後
// 削除後に非アクティブになることを確認してフレームを進める
Assert.AreEqual(1, service.StepCount);
manager.SetActiveService(true);
Assert.IsTrue(manager.IsActiveService());
manager.RemoveService();
Assert.IsFalse(manager.IsActiveService());
yield return null;
// サービスは生成直後にアクティブを切ると起動処理すら呼ばれないことを確認する
service = new ServiceBaseA();
manager.AddService(service);
Assert.AreEqual(0, service.StepCount);
Assert.IsFalse(service.Startuped);
Assert.IsTrue(manager.IsActiveService());
manager.SetActiveService(false);
yield return null;
Assert.AreEqual(0, service.StepCount);
Assert.IsFalse(service.Startuped);
Assert.IsFalse(manager.IsActiveService());
// サービスを削除してフレームを進める
manager.RemoveService();
yield return null;
}
///
/// サービスの起動停止の処理が想定タイミングで行われるかをテストします
///
/// Unityのフレーム待機をするための列挙子を返します
[UnityTest, Order(60)]
public IEnumerator StartupAndShutdownTest()
{
// サービスの起動と停止はフレームの開始や終了のタイミングのため
// 生成直後や削除要求直後はまだステータス変化が起きていないことを確認する
// サービスを生成、登録後にまだ起動処理が呼び出されていないことを確認して、フレームを進める
var service = new ServiceBaseA();
manager.AddService(service);
Assert.IsFalse(service.Startuped);
yield return null;
// サービスが起動したことを確認して、削除要求後にまだシャットダウンされていない事を確認して、フレームを進める
Assert.IsTrue(service.Startuped);
manager.RemoveService();
Assert.IsFalse(service.Stopped);
yield return null;
// サービスが停止したことを確認する
Assert.IsTrue(service.Stopped);
// 新たにサービスを生成して追加後にアクティブを切ったら、フレームが進んでも起動しないことを確認する
service = new ServiceBaseA();
manager.AddService(service);
manager.SetActiveService(false);
Assert.IsFalse(service.Startuped);
yield return null;
Assert.IsFalse(service.Startuped);
// 寝たままの状態で削除されてもシャットダウンされないことを確認する
manager.RemoveService();
yield return null;
Assert.IsFalse(service.Stopped);
// 新たにサービスを生成してアクティブを切った後、フレーム更新中にアクティブを戻して削除してもシャットダウンが呼ばれないことを確認する
service = new ServiceBaseA();
manager.AddService(service);
manager.SetActiveService(false);
yield return null;
manager.AddService(new ServiceBaseARemoveService());
yield return null;
Assert.IsFalse(service.Stopped);
manager.RemoveService();
yield return null;
}
///
/// サービスの存在チェックが正しく行われるかをテストします。
///
/// Unityのフレーム待機をするための列挙子を返します
[UnityTest, Order(70)]
public IEnumerator ExistsTest()
{
// サービス全確認ができない関数
var allNotExists = new Action(() =>
{
// すべてのサービスの存在を確認できない場合の処理
Assert.IsFalse(manager.Exists()); // 最基底クラスはそもそも検索や存在確認で利用できない
Assert.IsFalse(manager.Exists());
Assert.IsFalse(manager.Exists());
Assert.IsFalse(manager.Exists());
Assert.IsFalse(manager.Exists());
Assert.IsFalse(manager.Exists());
Assert.IsFalse(manager.Exists());
Assert.IsFalse(manager.Exists());
Assert.IsFalse(manager.Exists());
});
// サービスの部分確認が出来る関数
var existsPass = new Action(() =>
{
// 部分的なサービス存在が可能な場合の処理
Assert.IsFalse(manager.Exists()); // 最基底クラスはそもそも検索や存在確認で利用できない
Assert.IsTrue(manager.Exists()); // A2_0の継承元
Assert.IsTrue(manager.Exists()); // A2_0の継承元
Assert.IsTrue(manager.Exists()); // A2_0ご本人様
Assert.IsFalse(manager.Exists()); // A2_0とは関係のないサービス
Assert.IsTrue(manager.Exists()); // B1_0の継承元
Assert.IsTrue(manager.Exists()); // B1_0ご本人様
Assert.IsFalse(manager.Exists()); // B1_0を継承しているがB1_0から見たら関係ないサービス
Assert.IsFalse(manager.Exists()); // B1_0を継承しているがB1_0から見たら関係ないサービス
});
// 現時点では全サービスは存在していないはず
allNotExists();
// サービスを追加すると直ちに存在確認が出来る事を確認して、フレームを進める
manager.AddService(new ServiceA_2_0());
manager.AddService(new ServiceB_1_0());
existsPass();
yield return null;
// アクティブを切っても存在チェックは通る事を確認する
manager.SetActiveService(false);
manager.SetActiveService(false);
existsPass();
// 削除対象になってもそのフレームの間は存在チェックが通ることを確認して、フレームを進める
manager.RemoveService();
manager.RemoveService();
existsPass();
yield return null;
// すべて削除されたはずなら、全サービスは存在していないはず
allNotExists();
}
#endregion
}
}