public void GetDoDelayOperationsEnumeratorPasses() { var root = new ModelClass() { Name = "root" }; var apple = new ModelClass() { Name = "apple" }; var grape = new ModelClass() { Name = "grape" }; root.AddChildren(apple, grape); var orange = new ModelClass() { Name = "orange" }; grape.AddChildren(orange); var allBinder = new ModelViewBinder("*", null, new ModelViewBinder.BindInfo(typeof(IntViewObjClass))); var viewInstanceCreator = new DefaultViewInstanceCreator( (typeof(IntViewObjClass), new IntViewObjClass.Binder()), (typeof(FloatViewObjClass), new FloatViewObjClass.Binder()) ); var binderMap = new ModelViewBinderMap(viewInstanceCreator, allBinder); var bindInstanceMap = new ModelViewBinderInstanceMap(binderMap); Assert.IsFalse(bindInstanceMap.EnabledDelayOperation); bindInstanceMap.EnabledDelayOperation = true; {//操作は対象になっているIModel分だけ生成されるようにする bindInstanceMap.Add(false, null, root.GetHierarchyEnumerable()); bindInstanceMap.Remove(root.GetHierarchyEnumerable()); var correctOpCount = root.GetHierarchyEnumerable().Count(); var enumerator = bindInstanceMap.GetDoDelayOperationsEnumerator(); var opCount = 0; while (enumerator.MoveNext() && enumerator.Current != null) { opCount++; } Assert.AreEqual(correctOpCount, opCount, "登録された操作の個数が想定されたものになっていません。操作対象となっているIModelの数だけ操作を生成してくください。"); bindInstanceMap.Add(false, null, root.GetHierarchyEnumerable()); correctOpCount = root.GetHierarchyEnumerable().Count(); opCount = 0; while (enumerator.MoveNext() && enumerator.Current != null) { opCount++; } Assert.AreEqual(correctOpCount, opCount, "再び操作が追加された後でも、ModelViewBinderInstanceMap#GetDoDelayOperationsEnumerator関数の返り値のIEnumeratorが使用できるようにしてください。"); } }
/// <summary> /// /// </summary> /// <param name="binderInstanceMap"></param> /// <param name="eventInterruptedData"></param> /// <returns>trueなら割り込み対象になったイベントを即時送信することを表します。</returns> public bool Interrupt(ModelViewBinderInstanceMap binderInstanceMap, EventInterruptedData eventInterruptedData) { OnEventInterruptCallback matchPredicate = GetInterruptCallback(eventInterruptedData); Assert.IsNotNull(matchPredicate); var(createdModel, doSendImmediate) = matchPredicate(binderInstanceMap, eventInterruptedData); if (createdModel != null) { if (!binderInstanceMap.BindInstances.ContainsKey(createdModel)) { Assert.IsTrue(binderInstanceMap.BinderMap.Binders.Any(_b => _b.DoMatch(createdModel)), $"OnEventInterruptCallbackで生成したModelは必ずModelViewBinderInstanceMapに追加されるようにしてください。"); binderInstanceMap.Add(createdModel, false, (binderInstance) => { binderInstance.HoldedEventInterruptedData = eventInterruptedData; }); } else { binderInstanceMap.BindInstances[createdModel].HoldedEventInterruptedData = eventInterruptedData; } } return(doSendImmediate); }
public void OnAddedCallbackPasses() { var allBinder = new ModelViewBinder("*", null, new ModelViewBinder.BindInfo(typeof(TestOnCreatedViewObjClass))); var viewInstanceCreator = new DefaultViewInstanceCreator( (typeof(TestOnCreatedViewObjClass), new TestOnCreatedViewObjClass.ParamBinder()) ); {//ModeViewBinder#CreateViewObjectsのテスト var counter = 0; List <ModelViewBinderInstance> onAddedBinderInstanceList = new List <ModelViewBinderInstance>(); ModelViewBinderMap.OnAddedCallback onAddedCallback = (binderInstance) => { counter++; onAddedBinderInstanceList.Add(binderInstance); }; var binderMap = new ModelViewBinderMap(viewInstanceCreator, allBinder) { DefaultOnAddedCallback = onAddedCallback }; Assert.AreSame(onAddedCallback, binderMap.DefaultOnAddedCallback); var binderInstanceMap = new ModelViewBinderInstanceMap(binderMap); var root = new Model() { Name = "root" }; {// counter = 0; onAddedBinderInstanceList.Clear(); binderInstanceMap.RootModel = root; Assert.AreEqual(1, counter); AssertionUtils.AssertEnumerableByUnordered( new ModelViewBinderInstance[] { binderInstanceMap.BindInstances[root] } , onAddedBinderInstanceList , ""); } {//親子階層を持つModelを追加した時のテスト var model = new Model() { Name = "model1" }; var child = new Model() { Name = "child1" }; child.Parent = model; counter = 0; onAddedBinderInstanceList.Clear(); binderInstanceMap.Add(model, false, null); Assert.AreEqual(2, counter); AssertionUtils.AssertEnumerableByUnordered( new ModelViewBinderInstance[] { binderInstanceMap.BindInstances[model], binderInstanceMap.BindInstances[child], } , onAddedBinderInstanceList , ""); } {//Default意外にもカールバックを設定した時のテスト. var model = new Model() { Name = "model1" }; counter = 0; onAddedBinderInstanceList.Clear(); var tmpCounter = 0; binderInstanceMap.Add(model, false, (binderInstance) => { tmpCounter += 100; onAddedBinderInstanceList.Add(binderInstance); }); Assert.AreEqual(1, counter); Assert.AreEqual(100, tmpCounter); AssertionUtils.AssertEnumerableByUnordered( new ModelViewBinderInstance[] { binderInstanceMap.BindInstances[model], binderInstanceMap.BindInstances[model], } , onAddedBinderInstanceList , "引数に渡したコールバックとDefaultのコールバック両方とも呼び出すようにしてください"); } } }
public void IViewObjectOnCreatedPasses() { var allBinder = new ModelViewBinder("*", null, new ModelViewBinder.BindInfo(typeof(TestOnCreatedViewObjClass))); var viewInstanceCreator = new DefaultViewInstanceCreator( (typeof(TestOnCreatedViewObjClass), new TestOnCreatedViewObjClass.ParamBinder()) ); var errorMessageUseModel = $"ModeViewBinder#CreateViewObjectsに渡したModelがIViewObject#UseModelに設定されるようにしてください"; var errorMessageUseBinderInstance = $"ModeViewBinder#CreateViewObjectsに渡したModelViewBinderInstanceがIViewObject#UseBinderInstanceに設定されるようにしてください"; var errorMessageUsedBinderInstanceMap = $"ModeViewBinder#CreateViewObjectsに渡したModelViewBinderInstanceMapがIViewObject#OnCreatedに渡されるようにしてください"; {//ModeViewBinder#CreateViewObjectsのテスト var binderMap = new ModelViewBinderMap(viewInstanceCreator, allBinder); var binderInstanceMap = new ModelViewBinderInstanceMap(binderMap); var root = new Model() { Name = "root" }; var viewObjs = allBinder.CreateViewObjects(root, null, binderInstanceMap); Assert.AreEqual(1, viewObjs.Count); var viewObj = viewObjs[0]; Assert.AreSame(root, viewObj.UseModel, errorMessageUseModel); Assert.AreSame(null, viewObj.UseBinderInstance, errorMessageUseBinderInstance); var onCreatedViewObj = viewObjs[0] as TestOnCreatedViewObjClass; Assert.AreSame(binderInstanceMap, onCreatedViewObj.UsedBinderInstanceMap, errorMessageUsedBinderInstanceMap); } { //ModelViewBinderInstanceMapを指定しなかった時のテスト var root = new Model() { Name = "root" }; var viewObjs = allBinder.CreateViewObjects(root, null, null); Assert.AreEqual(1, viewObjs.Count); var viewObj = viewObjs[0]; Assert.AreSame(root, viewObj.UseModel, errorMessageUseModel); var onCreatedViewObj = viewObj as TestOnCreatedViewObjClass; Assert.AreSame(null, onCreatedViewObj.UsedBinderInstanceMap, errorMessageUsedBinderInstanceMap); } {//ModelViewBinderInstanceMap#CreateBindInstanceのテスト var binderMap = new ModelViewBinderMap(viewInstanceCreator, allBinder); var binderInstanceMap = new ModelViewBinderInstanceMap(binderMap); var root = new Model() { Name = "root" }; var bindInstance = binderMap.CreateBindInstance(root, binderInstanceMap); Assert.AreEqual(1, bindInstance.ViewObjects.Count()); var viewObj = bindInstance.ViewObjects.First(); Assert.AreSame(root, viewObj.UseModel, errorMessageUseModel); Assert.AreSame(bindInstance, viewObj.UseBinderInstance, errorMessageUseBinderInstance); var onCreatedViewObj = viewObj as TestOnCreatedViewObjClass; Assert.AreSame(binderInstanceMap, onCreatedViewObj.UsedBinderInstanceMap, errorMessageUsedBinderInstanceMap); } {//ModelViewBinderInstanceMap#Addのテスト var binderMap = new ModelViewBinderMap(viewInstanceCreator, allBinder); var binderInstanceMap = new ModelViewBinderInstanceMap(binderMap); var root = new Model() { Name = "root" }; binderInstanceMap.Add(root); var bindInstance = binderInstanceMap.BindInstances[root]; Assert.AreEqual(1, bindInstance.ViewObjects.Count()); var viewObj = bindInstance.ViewObjects.First(); Assert.AreSame(root, viewObj.UseModel, errorMessageUseModel); var onCreatedViewObj = viewObj as TestOnCreatedViewObjClass; Assert.AreSame(binderInstanceMap, onCreatedViewObj.UsedBinderInstanceMap, errorMessageUsedBinderInstanceMap); } }
public void DelayOperationPasses() { var root = new ModelClass() { Name = "root" }; var apple = new ModelClass() { Name = "apple" }; var grape = new ModelClass() { Name = "grape" }; root.AddChildren(apple, grape); var orange = new ModelClass() { Name = "orange" }; grape.AddChildren(orange); var allBinder = new ModelViewBinder("*", null, new ModelViewBinder.BindInfo(typeof(IntViewObjClass))); var viewInstanceCreator = new DefaultViewInstanceCreator( (typeof(IntViewObjClass), new IntViewObjClass.Binder()), (typeof(FloatViewObjClass), new FloatViewObjClass.Binder()) ); var binderMap = new ModelViewBinderMap(viewInstanceCreator, allBinder); var bindInstanceMap = new ModelViewBinderInstanceMap(binderMap); Assert.IsFalse(bindInstanceMap.EnabledDelayOperation); bindInstanceMap.EnabledDelayOperation = true; {//追加 bindInstanceMap.Add(false, null, root.GetHierarchyEnumerable()); Assert.IsFalse(bindInstanceMap.BindInstances.Any(), "遅延操作が有効になっている場合はBindInstanceMap#DoDelayOperation()を呼び出されるまで、追加処理を実行しないでください。"); bindInstanceMap.DoDelayOperations(); Assert.IsTrue(bindInstanceMap.BindInstances.Any()); {//一度操作が実行された後は同じ操作を繰り返し実行されないようにする var e = bindInstanceMap.GetDoDelayOperationsEnumerator(); var opCount = 0; while (e.MoveNext() && e.Current != null) { opCount++; } Assert.AreEqual(0, opCount, "一度操作を実行した後はそれを削除するようにしてください"); } } { //更新 Model#OnUpdatedが呼び出されるかどうかでテストしている var viewObj = bindInstanceMap.BindInstances[root].ViewObjects.First() as IntViewObjClass; { //ModelViewBindInstanceMap#UpdateViewObjects() root.IntValue = 9874; bindInstanceMap.UpdateViewObjects(); Assert.AreNotEqual(viewObj.IntValue, root.IntValue, $"遅延操作が有効な時は、ModelViewBindInstanceMap#DoDelayOperation()が呼び出されるまで更新処理を実行しないでください。"); bindInstanceMap.DoDelayOperations(); Assert.AreEqual(viewObj.IntValue, root.IntValue, $"遅延操作が更新に対応していません。"); } {//Model#DoneUpdate() root.IntValue++; root.DoneUpdate(); Assert.AreNotEqual(viewObj.IntValue, root.IntValue, $"遅延操作が有効な時は、ModelViewBindInstanceMap#DoDelayOperation()が呼び出されるまで更新処理を実行しないでください。"); bindInstanceMap.DoDelayOperations(); Assert.AreEqual(viewObj.IntValue, root.IntValue, $"遅延操作が更新に対応していません。"); } } {//削除 var instanceCount = bindInstanceMap.BindInstances.Count(); bindInstanceMap.Remove(bindInstanceMap.BindInstances.Keys); Assert.AreEqual(instanceCount, bindInstanceMap.BindInstances.Count() , "遅延操作が有効になっている場合はBindInstanceMap#DoDelayOperation()を呼び出されるまで、削除処理を実行しないでください。"); bindInstanceMap.DoDelayOperations(); Assert.IsFalse(bindInstanceMap.BindInstances.Any()); } {//追加と削除が合わせて遅延処理に登録されていたら、何もしないようにする bindInstanceMap.Add(false, null, root.GetHierarchyEnumerable()); bindInstanceMap.Remove(root.GetHierarchyEnumerable()); Assert.IsFalse(bindInstanceMap.BindInstances.Any(), "遅延操作が有効になっている場合はBindInstanceMap#DoDelayOperation()を呼び出されるまで、追加・削除処理を実行しないでください。"); bindInstanceMap.DoDelayOperations(); Assert.IsFalse(bindInstanceMap.BindInstances.Any(), "同じModelの追加・削除を遅延処理で同時に実行される場合は何もしないようにしてください"); } }
public void BinderInstanceMapBasicUsagePasses() { var root = new ModelClass() { Name = "root" }; var apple = new ModelClass() { Name = "apple" }; var noneBinderModel = new ModelClass() { Name = "grape" }; root.AddChildren(apple, noneBinderModel); var orange = new ModelClass() { Name = "orange" }; noneBinderModel.AddChildren(orange); var appleBinder = new ModelViewBinder("apple", null, new ModelViewBinder.BindInfo(typeof(IntViewObjClass))); var orangeBinder = new ModelViewBinder("orange", null, new ModelViewBinder.BindInfo(typeof(FloatViewObjClass))); var rebindBinder = new ModelViewBinder("Rebind", null, new ModelViewBinder.BindInfo(typeof(FloatViewObjClass))); Assert.IsFalse(root.DoMatchQueryPath(appleBinder.Query)); var viewInstanceCreator = new DefaultViewInstanceCreator( (typeof(IntViewObjClass), new IntViewObjClass.Binder()), (typeof(FloatViewObjClass), new FloatViewObjClass.Binder()) ); var binderMap = new ModelViewBinderMap(viewInstanceCreator, appleBinder, orangeBinder, rebindBinder); {//BinderInstanceMapのテスト var bindInstanceMap = new ModelViewBinderInstanceMap(binderMap); Assert.AreSame(binderMap, bindInstanceMap.BinderMap); {//BindInstanceMap#Addのテスト Assert.AreEqual(0, bindInstanceMap.BindInstances.Count()); bindInstanceMap.Add(false, null, apple, noneBinderModel); //grapeはQueryPathと一致しないので追加されない AssertionUtils.AssertEnumerableByUnordered(new Model[] { apple, orange }, bindInstanceMap.BindInstances.Select(_b => _b.Key), ""); //追加された時は合わせてViewのパラメータもModelのものに更新する var appleViewObj = bindInstanceMap[apple].ViewObjects.First(_v => _v is IntViewObjClass) as IntViewObjClass; Assert.AreEqual(apple.IntValue, appleViewObj.IntValue); foreach (var viewObj in bindInstanceMap[apple].ViewObjects) { Assert.AreEqual(bindInstanceMap[apple], viewObj.UseBinderInstance); } Assert.AreSame(bindInstanceMap, bindInstanceMap[apple].UseInstanceMap); var orangeViewObj = bindInstanceMap[orange].ViewObjects.First(_v => _v is FloatViewObjClass) as FloatViewObjClass; Assert.AreEqual(orange.FloatValue, orangeViewObj.FloatValue); foreach (var viewObj in bindInstanceMap[orange].ViewObjects) { Assert.AreEqual(bindInstanceMap[orange], viewObj.UseBinderInstance); } //既に追加されていたら追加しない bindInstanceMap.Add(false, null, apple, orange); AssertionUtils.AssertEnumerableByUnordered(new Model[] { apple, orange }, bindInstanceMap.BindInstances.Select(_b => _b.Key), "同じModelが追加できないようにしてください"); } {//マッチしないModelを追加した時のテスト var empty = new Model() { Name = "__empty" }; Assert.DoesNotThrow(() => { bindInstanceMap.Add(empty); Assert.IsFalse(bindInstanceMap.BindInstances.ContainsKey(empty), "マッチしないModelを追加した時はModelViewBinderInstanceを生成しないようにしてください"); }, "マッチしないModelを追加した時でもModelViewBinderInstanceMapから例外を発生させないようにしてください。"); } var appleBindInstance = bindInstanceMap[apple]; var orangeBindInstance = bindInstanceMap[orange]; {//BindInstanceMap#[]のテスト Assert.IsNotNull(appleBindInstance); Assert.AreEqual(apple, appleBindInstance.Model); Assert.IsNotNull(orangeBindInstance); Assert.AreEqual(orange, orangeBindInstance.Model); } {//BindInstanceMap#UpdateViewObjectsのテスト apple.IntValue = 234; orange.FloatValue = 2.5432f; bindInstanceMap.UpdateViewObjects(); var appleViewObj = appleBindInstance.ViewObjects.First(_v => _v is IntViewObjClass) as IntViewObjClass; Assert.AreEqual(apple.IntValue, appleViewObj.IntValue); var orangeViewObj = orangeBindInstance.ViewObjects.First(_v => _v is FloatViewObjClass) as FloatViewObjClass; Assert.AreEqual(orange.FloatValue, orangeViewObj.FloatValue); } {//BindInstanceMap#Rebindのテスト apple.Name = "Rebind"; var isSuccess = bindInstanceMap.Rebind(apple); Assert.IsTrue(isSuccess, "Rebindに失敗しています"); Assert.AreSame(rebindBinder, bindInstanceMap.BindInstances[apple].Binder); Assert.AreSame(bindInstanceMap, bindInstanceMap.BindInstances[apple].UseInstanceMap); } { // 追加されていないものをRebindした時は何もしない var recordedBindInstances = bindInstanceMap.BindInstances.ToArray(); var model = new ModelClass() { Name = "Tmp" }; var isSuccess = bindInstanceMap.Rebind(model); Assert.IsFalse(isSuccess, "登録されていないModelの場合はRebindしないようにしてください"); AssertionUtils.AssertEnumerable(recordedBindInstances, bindInstanceMap.BindInstances, "ModelViewBinderInstanceMapに追加されていないModelをRebindした時は何もしないようにしてください。"); } {//BindInstanceMap#Removeのテスト bindInstanceMap.Remove(apple, noneBinderModel); Assert.AreEqual(0, bindInstanceMap.BindInstances.Count()); } {//BindInstanceMap#ClearBindInstancesのテスト bindInstanceMap.Add(false, null, apple, orange); bindInstanceMap.ClearBindInstances(); Assert.AreEqual(0, bindInstanceMap.BindInstances.Count()); } } }